/*
 * Copyright (c) 2016, 2025, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2016, 2024 SAP SE. 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 "asm/macroAssembler.inline.hpp"
#include "compiler/disassembler.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/tlab_globals.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/interpreterRuntime.hpp"
#include "interpreter/interp_masm.hpp"
#include "interpreter/templateTable.hpp"
#include "memory/universe.hpp"
#include "oops/klass.inline.hpp"
#include "oops/methodCounters.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "oops/resolvedFieldEntry.hpp"
#include "oops/resolvedIndyEntry.hpp"
#include "oops/resolvedMethodEntry.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/methodHandles.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/safepointMechanism.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/synchronizer.hpp"
#include "utilities/macros.hpp"
#include "utilities/powerOfTwo.hpp"

#ifdef PRODUCT
#define __ _masm->
#define BLOCK_COMMENT(str)
#define BIND(label)        __ bind(label);
#else
#define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
// #define __ (PRODUCT_ONLY(false&&)Verbose ? (_masm->block_comment(FILE_AND_LINE),_masm):_masm)->
#define BLOCK_COMMENT(str) __ block_comment(str)
#define BIND(label)        __ bind(label); BLOCK_COMMENT(#label ":")
#endif

// The assumed minimum size of a BranchTableBlock.
// The actual size of each block heavily depends on the CPU capabilities and,
// of course, on the logic implemented in each block.
#ifdef ASSERT
// With introduced assert in get_monitor() & set_monitor(), required block size is now 322.
  #define BTB_MINSIZE 512
#else
  #define BTB_MINSIZE  64
#endif

#ifdef ASSERT
// Macro to open a BranchTableBlock (a piece of code that is branched to by a calculated branch).
#define BTB_BEGIN(lbl, alignment, name)                                        \
  __ align_address(alignment);                                                 \
  __ bind(lbl);                                                                \
  { unsigned int b_off = __ offset();                                          \
    uintptr_t   b_addr = (uintptr_t)__ pc();                                   \
    __ z_larl(br_tab_temp, (int64_t)0);  /* Check current address alignment. */\
    __ z_slgr(br_tab_temp, br_tab);      /* Current Address must be equal    */\
    __ z_brc(Assembler::bcondLogZero, 3);/* skip trap if ok. */                \
    __ z_illtrap(0x55);                                                        \
    guarantee(b_addr%alignment == 0, "bad alignment at begin of block" name);

// Macro to close a BranchTableBlock (a piece of code that is branched to by a calculated branch).
#define BTB_END(lbl, alignment, name)                                          \
    uintptr_t   e_addr = (uintptr_t)__ pc();                                   \
    unsigned int e_off = __ offset();                                          \
    unsigned int len   = e_off-b_off;                                          \
    if (len > alignment) {                                                     \
      tty->print_cr("%4d of %4d @ " INTPTR_FORMAT ": Block len for %s",        \
                    len, alignment, e_addr-len, name);                         \
      guarantee(len <= alignment, "block too large, len = %d, alignment = %d", \
                      len, alignment);                                         \
    }                                                                          \
    guarantee(len == e_addr-b_addr, "block len mismatch");                     \
  }
#else
// Macro to open a BranchTableBlock (a piece of code that is branched to by a calculated branch).
#define BTB_BEGIN(lbl, alignment, name)                                        \
  __ align_address(alignment);                                                 \
  __ bind(lbl);                                                                \
  { unsigned int b_off = __ offset();                                          \
    uintptr_t   b_addr = (uintptr_t)__ pc();                                   \
    guarantee(b_addr%alignment == 0, "bad alignment at begin of block" name);

// Macro to close a BranchTableBlock (a piece of code that is branched to by a calculated branch).
#define BTB_END(lbl, alignment, name)                                          \
    uintptr_t   e_addr = (uintptr_t)__ pc();                                   \
    unsigned int e_off = __ offset();                                          \
    unsigned int len   = e_off-b_off;                                          \
    if (len > alignment) {                                                     \
      tty->print_cr("%4d of %4d @ " INTPTR_FORMAT ": Block len for %s",        \
                    len, alignment, e_addr-len, name);                         \
      guarantee(len <= alignment, "block too large, len = %d, alignment = %d", \
                      len, alignment);                                         \
    }                                                                          \
    guarantee(len == e_addr-b_addr, "block len mismatch");                     \
  }
#endif // ASSERT

// Address computation: local variables

static inline Address iaddress(int n) {
  return Address(Z_locals, Interpreter::local_offset_in_bytes(n));
}

static inline Address laddress(int n) {
  return iaddress(n + 1);
}

static inline Address faddress(int n) {
  return iaddress(n);
}

static inline Address daddress(int n) {
  return laddress(n);
}

static inline Address aaddress(int n) {
  return iaddress(n);
}

// Pass null, if no shift instruction should be emitted.
static inline Address iaddress(InterpreterMacroAssembler *masm, Register r) {
  if (masm) {
    masm->z_sllg(r, r, LogBytesPerWord);  // index2bytes
  }
  return Address(Z_locals, r, Interpreter::local_offset_in_bytes(0));
}

// Pass null, if no shift instruction should be emitted.
static inline Address laddress(InterpreterMacroAssembler *masm, Register r) {
  if (masm) {
    masm->z_sllg(r, r, LogBytesPerWord);  // index2bytes
  }
  return Address(Z_locals, r, Interpreter::local_offset_in_bytes(1) );
}

static inline Address faddress(InterpreterMacroAssembler *masm, Register r) {
  return iaddress(masm, r);
}

static inline Address daddress(InterpreterMacroAssembler *masm, Register r) {
  return laddress(masm, r);
}

static inline Address aaddress(InterpreterMacroAssembler *masm, Register r) {
  return iaddress(masm, r);
}

// At top of Java expression stack which may be different than esp(). It
// isn't for category 1 objects.
static inline Address at_tos(int slot = 0) {
  return Address(Z_esp, Interpreter::expr_offset_in_bytes(slot));
}

// Condition conversion
static Assembler::branch_condition j_not(TemplateTable::Condition cc) {
  switch (cc) {
    case TemplateTable::equal :
      return Assembler::bcondNotEqual;
    case TemplateTable::not_equal :
      return Assembler::bcondEqual;
    case TemplateTable::less :
      return Assembler::bcondNotLow;
    case TemplateTable::less_equal :
      return Assembler::bcondHigh;
    case TemplateTable::greater :
      return Assembler::bcondNotHigh;
    case TemplateTable::greater_equal:
      return Assembler::bcondLow;
  }
  ShouldNotReachHere();
  return Assembler::bcondZero;
}

// Do an oop store like *(base + offset) = val
// offset can be a register or a constant.
static void do_oop_store(InterpreterMacroAssembler* _masm,
                         const Address&     addr,
                         Register           val,         // Noreg means always null.
                         Register           tmp1,
                         Register           tmp2,
                         Register           tmp3,
                         DecoratorSet       decorators) {
  assert_different_registers(tmp1, tmp2, tmp3, val, addr.base());
  __ store_heap_oop(val, addr, tmp1, tmp2, tmp3, decorators);
}

static void do_oop_load(InterpreterMacroAssembler* _masm,
                        const Address& addr,
                        Register dst,
                        Register tmp1,
                        Register tmp2,
                        DecoratorSet decorators) {
  assert_different_registers(addr.base(), tmp1, tmp2);
  assert_different_registers(dst, tmp1, tmp2);
  __ load_heap_oop(dst, addr, tmp1, tmp2, decorators);
}

Address TemplateTable::at_bcp(int offset) {
  assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
  return Address(Z_bcp, offset);
}

void TemplateTable::patch_bytecode(Bytecodes::Code bc,
                                   Register        bc_reg,
                                   Register        temp_reg,
                                   bool            load_bc_into_bc_reg, // = true
                                   int             byte_no) {
  if (!RewriteBytecodes) { return; }

  NearLabel L_patch_done;
  BLOCK_COMMENT("patch_bytecode {");

  switch (bc) {
    case Bytecodes::_fast_aputfield:
    case Bytecodes::_fast_bputfield:
    case Bytecodes::_fast_zputfield:
    case Bytecodes::_fast_cputfield:
    case Bytecodes::_fast_dputfield:
    case Bytecodes::_fast_fputfield:
    case Bytecodes::_fast_iputfield:
    case Bytecodes::_fast_lputfield:
    case Bytecodes::_fast_sputfield:
      {
        // We skip bytecode quickening for putfield instructions when
        // the put_code written to the constant pool cache is zero.
        // This is required so that every execution of this instruction
        // calls out to InterpreterRuntime::resolve_get_put to do
        // additional, required work.
        assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
        assert(load_bc_into_bc_reg, "we use bc_reg as temp");

        // Both registers are block-local temp regs. Their contents before and after is not used.
        Register index = bc_reg;
        Register cache = temp_reg;

        __ load_field_entry(cache, index);
        __ load_const_optimized(bc_reg, bc);

        if (byte_no == f1_byte) {
          __ z_cli(Address(cache, in_bytes(ResolvedFieldEntry::get_code_offset())), 0);
        } else {
          __ z_cli(Address(cache, in_bytes(ResolvedFieldEntry::put_code_offset())), 0);
        }
        __ z_bre(L_patch_done);
      }
      break;
    default:
      assert(byte_no == -1, "sanity");
      // The bytecode pair may have already performed the load.
      if (load_bc_into_bc_reg) {
        __ load_const_optimized(bc_reg, bc);
      }
      break;
  }

  if (JvmtiExport::can_post_breakpoint()) {
    NearLabel L_fast_patch;

    // If a breakpoint is present we can't rewrite the stream directly.
    __ z_cli(at_bcp(0), Bytecodes::_breakpoint);
    __ z_brne(L_fast_patch);

    __ get_method(temp_reg);
    // Let breakpoint table handling rewrite to quicker bytecode.
    __ call_VM_static(noreg,
                      CAST_FROM_FN_PTR(address, InterpreterRuntime::set_original_bytecode_at),
                      temp_reg, Z_bcp, bc_reg);
    __ z_bru(L_patch_done);

    __ bind(L_fast_patch);
  }

#ifdef ASSERT
  NearLabel   L_okay;

  // We load into 64 bits, since this works on any CPU.
  __ z_llgc(temp_reg, at_bcp(0));
  __ compareU32_and_branch(temp_reg, Bytecodes::java_code(bc),
                            Assembler::bcondEqual, L_okay        );
  __ compareU32_and_branch(temp_reg, bc_reg, Assembler::bcondEqual, L_okay);
  __ stop_static("patching the wrong bytecode");
  __ bind(L_okay);
#endif

  // Patch bytecode.
  __ z_stc(bc_reg, at_bcp(0));

  __ bind(L_patch_done);
  BLOCK_COMMENT("} patch_bytecode");
}

// Individual instructions

void TemplateTable::nop() {
  transition(vtos, vtos);
}

void TemplateTable::shouldnotreachhere() {
  transition(vtos, vtos);
  __ stop("shouldnotreachhere bytecode");
}

void TemplateTable::aconst_null() {
  transition(vtos, atos);
  __ clear_reg(Z_tos, true, false);
}

void TemplateTable::iconst(int value) {
  transition(vtos, itos);
  // Zero extension of the iconst makes zero extension at runtime obsolete.
  __ load_const_optimized(Z_tos, ((unsigned long)(unsigned int)value));
}

void TemplateTable::lconst(int value) {
  transition(vtos, ltos);
  __ load_const_optimized(Z_tos, value);
}

// No pc-relative load/store for floats.
void TemplateTable::fconst(int value) {
  transition(vtos, ftos);
  static float   one = 1.0f, two = 2.0f;

  switch (value) {
    case 0:
      __ z_lzer(Z_ftos);
      return;
    case 1:
      __ load_absolute_address(Z_R1_scratch, (address) &one);
      __ mem2freg_opt(Z_ftos, Address(Z_R1_scratch), false);
      return;
    case 2:
      __ load_absolute_address(Z_R1_scratch, (address) &two);
      __ mem2freg_opt(Z_ftos, Address(Z_R1_scratch), false);
      return;
    default:
      ShouldNotReachHere();
      return;
  }
}

void TemplateTable::dconst(int value) {
  transition(vtos, dtos);
  static double one = 1.0;

  switch (value) {
    case 0:
      __ z_lzdr(Z_ftos);
      return;
    case 1:
      __ load_absolute_address(Z_R1_scratch, (address) &one);
      __ mem2freg_opt(Z_ftos, Address(Z_R1_scratch));
      return;
    default:
      ShouldNotReachHere();
      return;
  }
}

void TemplateTable::bipush() {
  transition(vtos, itos);
  __ z_lb(Z_tos, at_bcp(1));
}

void TemplateTable::sipush() {
  transition(vtos, itos);
  __ get_2_byte_integer_at_bcp(Z_tos, 1, InterpreterMacroAssembler::Signed);
}


void TemplateTable::ldc(LdcType type) {
  transition(vtos, vtos);
  Label call_ldc, notFloat, notClass, notInt, Done;
  const Register RcpIndex = Z_tmp_1;
  const Register Rtags = Z_ARG2;

  if (is_ldc_wide(type)) {
    __ get_2_byte_integer_at_bcp(RcpIndex, 1, InterpreterMacroAssembler::Unsigned);
  } else {
    __ z_llgc(RcpIndex, at_bcp(1));
  }

  __ get_cpool_and_tags(Z_tmp_2, Rtags);

  const int      base_offset = ConstantPool::header_size() * wordSize;
  const int      tags_offset = Array<u1>::base_offset_in_bytes();
  const Register Raddr_type = Rtags;

  // Get address of type.
  __ add2reg_with_index(Raddr_type, tags_offset, RcpIndex, Rtags);

  __ z_cli(0, Raddr_type, JVM_CONSTANT_UnresolvedClass);
  __ z_bre(call_ldc);    // Unresolved class - get the resolved class.

  __ z_cli(0, Raddr_type, JVM_CONSTANT_UnresolvedClassInError);
  __ z_bre(call_ldc);    // Unresolved class in error state - call into runtime
                         // to throw the error from the first resolution attempt.

  __ z_cli(0, Raddr_type, JVM_CONSTANT_Class);
  __ z_brne(notClass);   // Resolved class - need to call vm to get java
                         // mirror of the class.

  // We deal with a class. Call vm to do the appropriate.
  __ bind(call_ldc);
  __ load_const_optimized(Z_ARG2, is_ldc_wide(type) ? 1 : 0);
  call_VM(Z_RET, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), Z_ARG2);
  __ push_ptr(Z_RET);
  __ z_bru(Done);

  // Not a class.
  __ bind(notClass);
  Register RcpOffset = RcpIndex;
  __ z_sllg(RcpOffset, RcpIndex, LogBytesPerWord); // Convert index to offset.
  __ z_cli(0, Raddr_type, JVM_CONSTANT_Float);
  __ z_brne(notFloat);

  // ftos
  __ mem2freg_opt(Z_ftos, Address(Z_tmp_2, RcpOffset, base_offset), false);
  __ push_f();
  __ z_bru(Done);

  __ bind(notFloat);
  __ z_cli(0, Raddr_type, JVM_CONSTANT_Integer);
  __ z_brne(notInt);

  // itos
  __ mem2reg_opt(Z_tos, Address(Z_tmp_2, RcpOffset, base_offset), false);
  __ push_i(Z_tos);
  __ z_bru(Done);

  // assume the tag is for condy; if not, the VM runtime will tell us
  __ bind(notInt);
  condy_helper(Done);

  __ bind(Done);
}

// Fast path for caching oop constants.
// %%% We should use this to handle Class and String constants also.
// %%% It will simplify the ldc/primitive path considerably.
void TemplateTable::fast_aldc(LdcType type) {
  transition(vtos, atos);

  const Register index = Z_tmp_2;
  int            index_size = is_ldc_wide(type) ? sizeof(u2) : sizeof(u1);
  Label          L_do_resolve, L_resolved;

  // We are resolved if the resolved reference cache entry contains a
  // non-null object (CallSite, etc.).
  __ get_cache_index_at_bcp(index, 1, index_size);  // Load index.
  __ load_resolved_reference_at_index(Z_tos, index);
  __ z_ltgr(Z_tos, Z_tos);
  __ z_bre(L_do_resolve);

  // Convert null sentinel to null.
  __ load_const_optimized(Z_R1_scratch, (intptr_t)Universe::the_null_sentinel_addr());
  __ resolve_oop_handle(Z_R1_scratch);
  __ z_cg(Z_tos, Address(Z_R1_scratch));
  __ z_brne(L_resolved);
  __ clear_reg(Z_tos);
  __ z_bru(L_resolved);

  __ bind(L_do_resolve);
  // First time invocation - must resolve first.
  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
  __ load_const_optimized(Z_ARG1, (int)bytecode());
  __ call_VM(Z_tos, entry, Z_ARG1);

  __ bind(L_resolved);
  __ verify_oop(Z_tos);
}

void TemplateTable::ldc2_w() {
  transition(vtos, vtos);
  Label notDouble, notLong, Done;

  // Z_tmp_1 = index of cp entry
  __ get_2_byte_integer_at_bcp(Z_tmp_1, 1, InterpreterMacroAssembler::Unsigned);

  __ get_cpool_and_tags(Z_tmp_2, Z_tos);

  const int base_offset = ConstantPool::header_size() * wordSize;
  const int tags_offset = Array<u1>::base_offset_in_bytes();

  // Get address of type.
  __ add2reg_with_index(Z_tos, tags_offset, Z_tos, Z_tmp_1);

  // Index needed in both branches, so calculate here.
  __ z_sllg(Z_tmp_1, Z_tmp_1, LogBytesPerWord);  // index2bytes

  // Check type.
  __ z_cli(0, Z_tos, JVM_CONSTANT_Double);
  __ z_brne(notDouble);
  // dtos
  __ mem2freg_opt(Z_ftos, Address(Z_tmp_2, Z_tmp_1, base_offset));
  __ push_d();
  __ z_bru(Done);

  __ bind(notDouble);
  __ z_cli(0, Z_tos, JVM_CONSTANT_Long);
  __ z_brne(notLong);
  // ltos
  __ mem2reg_opt(Z_tos, Address(Z_tmp_2, Z_tmp_1, base_offset));
  __ push_l();
  __ z_bru(Done);

  __ bind(notLong);
  condy_helper(Done);

  __ bind(Done);
}

void TemplateTable::condy_helper(Label& Done) {
  const Register obj   = Z_tmp_1;
  const Register off   = Z_tmp_2;
  const Register flags = Z_ARG1;
  const Register rarg  = Z_ARG2;
  __ load_const_optimized(rarg, (int)bytecode());
  call_VM(obj, CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc), rarg);
  __ get_vm_result_metadata(flags);

  // VMr = obj = base address to find primitive value to push
  // VMr2 = flags = (tos, off) using format of CPCE::_flags
  assert(ConstantPoolCache::field_index_mask == 0xffff, "or use other instructions");
  __ z_llghr(off, flags);
  const Address field(obj, off);

  // What sort of thing are we loading?
  __ z_srl(flags, ConstantPoolCache::tos_state_shift);

  switch (bytecode()) {
  case Bytecodes::_ldc:
  case Bytecodes::_ldc_w:
    {
      // tos in (itos, ftos, stos, btos, ctos, ztos)
      Label notInt, notFloat, notShort, notByte, notChar, notBool;
      __ z_cghi(flags, itos);
      __ z_brne(notInt);
      // itos
      __ z_l(Z_tos, field);
      __ push(itos);
      __ z_bru(Done);

      __ bind(notInt);
      __ z_cghi(flags, ftos);
      __ z_brne(notFloat);
      // ftos
      __ z_le(Z_ftos, field);
      __ push(ftos);
      __ z_bru(Done);

      __ bind(notFloat);
      __ z_cghi(flags, stos);
      __ z_brne(notShort);
      // stos
      __ z_lh(Z_tos, field);
      __ push(stos);
      __ z_bru(Done);

      __ bind(notShort);
      __ z_cghi(flags, btos);
      __ z_brne(notByte);
      // btos
      __ z_lb(Z_tos, field);
      __ push(btos);
      __ z_bru(Done);

      __ bind(notByte);
      __ z_cghi(flags, ctos);
      __ z_brne(notChar);
      // ctos
      __ z_llh(Z_tos, field);
      __ push(ctos);
      __ z_bru(Done);

      __ bind(notChar);
      __ z_cghi(flags, ztos);
      __ z_brne(notBool);
      // ztos
      __ z_lb(Z_tos, field);
      __ push(ztos);
      __ z_bru(Done);

      __ bind(notBool);
      break;
    }

  case Bytecodes::_ldc2_w:
    {
      Label notLong, notDouble;
      __ z_cghi(flags, ltos);
      __ z_brne(notLong);
      // ltos
      __ z_lg(Z_tos, field);
      __ push(ltos);
      __ z_bru(Done);

      __ bind(notLong);
      __ z_cghi(flags, dtos);
      __ z_brne(notDouble);
      // dtos
      __ z_ld(Z_ftos, field);
      __ push(dtos);
      __ z_bru(Done);

      __ bind(notDouble);
      break;
    }

  default:
    ShouldNotReachHere();
  }

  __ stop("bad ldc/condy");
}

void TemplateTable::locals_index(Register reg, int offset) {
  __ z_llgc(reg, at_bcp(offset));
  __ z_lcgr(reg);
}

void TemplateTable::iload() {
  iload_internal();
}

void TemplateTable::nofast_iload() {
  iload_internal(may_not_rewrite);
}

void TemplateTable::iload_internal(RewriteControl rc) {
  transition(vtos, itos);

  if (RewriteFrequentPairs && rc == may_rewrite) {
    NearLabel rewrite, done;
    const Register bc = Z_ARG4;

    assert(Z_R1_scratch != bc, "register damaged");

    // Get next byte.
    __ z_llgc(Z_R1_scratch, at_bcp(Bytecodes::length_for (Bytecodes::_iload)));

    // If _iload, wait to rewrite to iload2. We only want to rewrite the
    // last two iloads in a pair. Comparing against fast_iload means that
    // the next bytecode is neither an iload or a caload, and therefore
    // an iload pair.
    __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_iload,
                             Assembler::bcondEqual, done);

    __ load_const_optimized(bc, Bytecodes::_fast_iload2);
    __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_fast_iload,
                             Assembler::bcondEqual, rewrite);

    // If _caload, rewrite to fast_icaload.
    __ load_const_optimized(bc, Bytecodes::_fast_icaload);
    __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_caload,
                             Assembler::bcondEqual, rewrite);

    // Rewrite so iload doesn't check again.
    __ load_const_optimized(bc, Bytecodes::_fast_iload);

    // rewrite
    // bc: fast bytecode
    __ bind(rewrite);
    patch_bytecode(Bytecodes::_iload, bc, Z_R1_scratch, false);

    __ bind(done);

  }

  // Get the local value into tos.
  locals_index(Z_R1_scratch);
  __ mem2reg_opt(Z_tos, iaddress(_masm, Z_R1_scratch), false);
}

void TemplateTable::fast_iload2() {
  transition(vtos, itos);

  locals_index(Z_R1_scratch);
  __ mem2reg_opt(Z_tos, iaddress(_masm, Z_R1_scratch), false);
  __ push_i(Z_tos);
  locals_index(Z_R1_scratch, 3);
  __ mem2reg_opt(Z_tos, iaddress(_masm, Z_R1_scratch), false);
}

void TemplateTable::fast_iload() {
  transition(vtos, itos);

  locals_index(Z_R1_scratch);
  __ mem2reg_opt(Z_tos, iaddress(_masm, Z_R1_scratch), false);
}

void TemplateTable::lload() {
  transition(vtos, ltos);

  locals_index(Z_R1_scratch);
  __ mem2reg_opt(Z_tos, laddress(_masm, Z_R1_scratch));
}

void TemplateTable::fload() {
  transition(vtos, ftos);

  locals_index(Z_R1_scratch);
  __ mem2freg_opt(Z_ftos, faddress(_masm, Z_R1_scratch), false);
}

void TemplateTable::dload() {
  transition(vtos, dtos);

  locals_index(Z_R1_scratch);
  __ mem2freg_opt(Z_ftos, daddress(_masm, Z_R1_scratch));
}

void TemplateTable::aload() {
  transition(vtos, atos);

  locals_index(Z_R1_scratch);
  __ mem2reg_opt(Z_tos, aaddress(_masm, Z_R1_scratch));
}

void TemplateTable::locals_index_wide(Register reg) {
  __ get_2_byte_integer_at_bcp(reg, 2, InterpreterMacroAssembler::Unsigned);
  __ z_lcgr(reg);
}

void TemplateTable::wide_iload() {
  transition(vtos, itos);

  locals_index_wide(Z_tmp_1);
  __ mem2reg_opt(Z_tos, iaddress(_masm, Z_tmp_1), false);
}

void TemplateTable::wide_lload() {
  transition(vtos, ltos);

  locals_index_wide(Z_tmp_1);
  __ mem2reg_opt(Z_tos, laddress(_masm, Z_tmp_1));
}

void TemplateTable::wide_fload() {
  transition(vtos, ftos);

  locals_index_wide(Z_tmp_1);
  __ mem2freg_opt(Z_ftos, faddress(_masm, Z_tmp_1), false);
}

void TemplateTable::wide_dload() {
  transition(vtos, dtos);

  locals_index_wide(Z_tmp_1);
  __ mem2freg_opt(Z_ftos, daddress(_masm, Z_tmp_1));
}

void TemplateTable::wide_aload() {
  transition(vtos, atos);

  locals_index_wide(Z_tmp_1);
  __ mem2reg_opt(Z_tos, aaddress(_masm, Z_tmp_1));
}

void TemplateTable::index_check(Register array, Register index, unsigned int shift) {
  assert_different_registers(Z_R1_scratch, array, index);

  // Sign extend index for use by indexed load.
  __ z_lgfr(index, index);

  // Check index.
  Label index_ok;
  __ z_cl(index, Address(array, arrayOopDesc::length_offset_in_bytes()));
  __ z_brl(index_ok);
  __ lgr_if_needed(Z_ARG3, index); // See generate_ArrayIndexOutOfBounds_handler().
  // Pass the array to create more detailed exceptions.
  __ lgr_if_needed(Z_ARG2, array); // See generate_ArrayIndexOutOfBounds_handler().
  __ load_absolute_address(Z_R1_scratch,
                           Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
  __ z_bcr(Assembler::bcondAlways, Z_R1_scratch);
  __ bind(index_ok);

  if (shift > 0)
    __ z_sllg(index, index, shift);
}

void TemplateTable::iaload() {
  transition(itos, itos);

  __ pop_ptr(Z_tmp_1);  // array
  // Index is in Z_tos.
  Register index = Z_tos;
  index_check(Z_tmp_1, index, LogBytesPerInt); // Kills Z_ARG3.
  // Load the value.
  __ mem2reg_opt(Z_tos,
                 Address(Z_tmp_1, index, arrayOopDesc::base_offset_in_bytes(T_INT)),
                 false);
}

void TemplateTable::laload() {
  transition(itos, ltos);

  __ pop_ptr(Z_tmp_2);
  // Z_tos   : index
  // Z_tmp_2 : array
  Register index = Z_tos;
  index_check(Z_tmp_2, index, LogBytesPerLong);
  __ mem2reg_opt(Z_tos,
                 Address(Z_tmp_2, index, arrayOopDesc::base_offset_in_bytes(T_LONG)));
}

void TemplateTable::faload() {
  transition(itos, ftos);

  __ pop_ptr(Z_tmp_2);
  // Z_tos   : index
  // Z_tmp_2 : array
  Register index = Z_tos;
  index_check(Z_tmp_2, index, LogBytesPerInt);
  __ mem2freg_opt(Z_ftos,
                  Address(Z_tmp_2, index, arrayOopDesc::base_offset_in_bytes(T_FLOAT)),
                  false);
}

void TemplateTable::daload() {
  transition(itos, dtos);

  __ pop_ptr(Z_tmp_2);
  // Z_tos   : index
  // Z_tmp_2 : array
  Register index = Z_tos;
  index_check(Z_tmp_2, index, LogBytesPerLong);
  __ mem2freg_opt(Z_ftos,
                  Address(Z_tmp_2, index, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
}

void TemplateTable::aaload() {
  transition(itos, atos);

  unsigned const int shift = LogBytesPerHeapOop;
  __ pop_ptr(Z_tmp_1);  // array
  // Index is in Z_tos.
  Register index = Z_tos;
  index_check(Z_tmp_1, index, shift);
  // Now load array element.
  do_oop_load(_masm, Address(Z_tmp_1, index, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), Z_tos,
              Z_tmp_2, Z_tmp_3, IS_ARRAY);
  __ verify_oop(Z_tos);
}

void TemplateTable::baload() {
  transition(itos, itos);

  __ pop_ptr(Z_tmp_1);
  // Z_tos   : index
  // Z_tmp_1 : array
  Register index = Z_tos;
  index_check(Z_tmp_1, index, 0);
  __ z_lb(Z_tos,
          Address(Z_tmp_1, index, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
}

void TemplateTable::caload() {
  transition(itos, itos);

  __ pop_ptr(Z_tmp_2);
  // Z_tos   : index
  // Z_tmp_2 : array
  Register index = Z_tos;
  index_check(Z_tmp_2, index, LogBytesPerShort);
  // Load into 64 bits, works on all CPUs.
  __ z_llgh(Z_tos,
            Address(Z_tmp_2, index, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
}

// Iload followed by caload frequent pair.
void TemplateTable::fast_icaload() {
  transition(vtos, itos);

  // Load index out of locals.
  locals_index(Z_R1_scratch);
  __ mem2reg_opt(Z_ARG3, iaddress(_masm, Z_R1_scratch), false);
  // Z_ARG3  : index
  // Z_tmp_2 : array
  __ pop_ptr(Z_tmp_2);
  index_check(Z_tmp_2, Z_ARG3, LogBytesPerShort);
  // Load into 64 bits, works on all CPUs.
  __ z_llgh(Z_tos,
            Address(Z_tmp_2, Z_ARG3, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
}

void TemplateTable::saload() {
  transition(itos, itos);

  __ pop_ptr(Z_tmp_2);
  // Z_tos   : index
  // Z_tmp_2 : array
  Register index = Z_tos;
  index_check(Z_tmp_2, index, LogBytesPerShort);
  __ z_lh(Z_tos,
          Address(Z_tmp_2, index, arrayOopDesc::base_offset_in_bytes(T_SHORT)));
}

void TemplateTable::iload(int n) {
  transition(vtos, itos);
  __ z_ly(Z_tos, iaddress(n));
}

void TemplateTable::lload(int n) {
  transition(vtos, ltos);
  __ z_lg(Z_tos, laddress(n));
}

void TemplateTable::fload(int n) {
  transition(vtos, ftos);
  __ mem2freg_opt(Z_ftos, faddress(n), false);
}

void TemplateTable::dload(int n) {
  transition(vtos, dtos);
  __ mem2freg_opt(Z_ftos, daddress(n));
}

void TemplateTable::aload(int n) {
  transition(vtos, atos);
  __ mem2reg_opt(Z_tos, aaddress(n));
}

void TemplateTable::aload_0() {
  aload_0_internal();
}

void TemplateTable::nofast_aload_0() {
  aload_0_internal(may_not_rewrite);
}

void TemplateTable::aload_0_internal(RewriteControl rc) {
  transition(vtos, atos);

  // According to bytecode histograms, the pairs:
  //
  // _aload_0, _fast_igetfield
  // _aload_0, _fast_agetfield
  // _aload_0, _fast_fgetfield
  //
  // occur frequently. If RewriteFrequentPairs is set, the (slow)
  // _aload_0 bytecode checks if the next bytecode is either
  // _fast_igetfield, _fast_agetfield or _fast_fgetfield and then
  // rewrites the current bytecode into a pair bytecode; otherwise it
  // rewrites the current bytecode into _fast_aload_0 that doesn't do
  // the pair check anymore.
  //
  // Note: If the next bytecode is _getfield, the rewrite must be
  //       delayed, otherwise we may miss an opportunity for a pair.
  //
  // Also rewrite frequent pairs
  //   aload_0, aload_1
  //   aload_0, iload_1
  // These bytecodes with a small amount of code are most profitable
  // to rewrite.
  if (!(RewriteFrequentPairs && (rc == may_rewrite))) {
    aload(0);
    return;
  }

  NearLabel rewrite, done;
  const Register bc = Z_ARG4;

  assert(Z_R1_scratch != bc, "register damaged");
  // Get next byte.
  __ z_llgc(Z_R1_scratch, at_bcp(Bytecodes::length_for (Bytecodes::_aload_0)));

  // Do actual aload_0.
  aload(0);

  // If _getfield then wait with rewrite.
  __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_getfield,
                           Assembler::bcondEqual, done);

  // If _igetfield then rewrite to _fast_iaccess_0.
  assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0)
            == Bytecodes::_aload_0, "fix bytecode definition");

  __ load_const_optimized(bc, Bytecodes::_fast_iaccess_0);
  __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_fast_igetfield,
                           Assembler::bcondEqual, rewrite);

  // If _agetfield then rewrite to _fast_aaccess_0.
  assert(Bytecodes::java_code(Bytecodes::_fast_aaccess_0)
            == Bytecodes::_aload_0, "fix bytecode definition");

  __ load_const_optimized(bc, Bytecodes::_fast_aaccess_0);
  __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_fast_agetfield,
                           Assembler::bcondEqual, rewrite);

  // If _fgetfield then rewrite to _fast_faccess_0.
  assert(Bytecodes::java_code(Bytecodes::_fast_faccess_0)
            == Bytecodes::_aload_0, "fix bytecode definition");

  __ load_const_optimized(bc, Bytecodes::_fast_faccess_0);
  __ compareU32_and_branch(Z_R1_scratch, Bytecodes::_fast_fgetfield,
                           Assembler::bcondEqual, rewrite);

  // Else rewrite to _fast_aload0.
  assert(Bytecodes::java_code(Bytecodes::_fast_aload_0)
            == Bytecodes::_aload_0, "fix bytecode definition");
  __ load_const_optimized(bc, Bytecodes::_fast_aload_0);

  // rewrite
  // bc: fast bytecode
  __ bind(rewrite);

  patch_bytecode(Bytecodes::_aload_0, bc, Z_R1_scratch, false);
  // Reload local 0 because of VM call inside patch_bytecode().
  // this may trigger GC and thus change the oop.
  aload(0);

  __ bind(done);
}

void TemplateTable::istore() {
  transition(itos, vtos);
  locals_index(Z_R1_scratch);
  __ reg2mem_opt(Z_tos, iaddress(_masm, Z_R1_scratch), false);
}

void TemplateTable::lstore() {
  transition(ltos, vtos);
  locals_index(Z_R1_scratch);
  __ reg2mem_opt(Z_tos, laddress(_masm, Z_R1_scratch));
}

void TemplateTable::fstore() {
  transition(ftos, vtos);
  locals_index(Z_R1_scratch);
  __ freg2mem_opt(Z_ftos, faddress(_masm, Z_R1_scratch));
}

void TemplateTable::dstore() {
  transition(dtos, vtos);
  locals_index(Z_R1_scratch);
  __ freg2mem_opt(Z_ftos, daddress(_masm, Z_R1_scratch));
}

void TemplateTable::astore() {
  transition(vtos, vtos);
  __ pop_ptr(Z_tos);
  locals_index(Z_R1_scratch);
  __ reg2mem_opt(Z_tos, aaddress(_masm, Z_R1_scratch));
}

void TemplateTable::wide_istore() {
  transition(vtos, vtos);
  __ pop_i(Z_tos);
  locals_index_wide(Z_tmp_1);
  __ reg2mem_opt(Z_tos, iaddress(_masm, Z_tmp_1), false);
}

void TemplateTable::wide_lstore() {
  transition(vtos, vtos);
  __ pop_l(Z_tos);
  locals_index_wide(Z_tmp_1);
  __ reg2mem_opt(Z_tos, laddress(_masm, Z_tmp_1));
}

void TemplateTable::wide_fstore() {
  transition(vtos, vtos);
  __ pop_f(Z_ftos);
  locals_index_wide(Z_tmp_1);
  __ freg2mem_opt(Z_ftos, faddress(_masm, Z_tmp_1), false);
}

void TemplateTable::wide_dstore() {
  transition(vtos, vtos);
  __ pop_d(Z_ftos);
  locals_index_wide(Z_tmp_1);
  __ freg2mem_opt(Z_ftos, daddress(_masm, Z_tmp_1));
}

void TemplateTable::wide_astore() {
  transition(vtos, vtos);
  __ pop_ptr(Z_tos);
  locals_index_wide(Z_tmp_1);
  __ reg2mem_opt(Z_tos, aaddress(_masm, Z_tmp_1));
}

void TemplateTable::iastore() {
  transition(itos, vtos);

  Register index = Z_ARG3; // Index_check expects index in Z_ARG3.
  // Value is in Z_tos ...
  __ pop_i(index);        // index
  __ pop_ptr(Z_tmp_1);    // array
  index_check(Z_tmp_1, index, LogBytesPerInt);
  // ... and then move the value.
  __ reg2mem_opt(Z_tos,
                 Address(Z_tmp_1, index, arrayOopDesc::base_offset_in_bytes(T_INT)),
                 false);
}

void TemplateTable::lastore() {
  transition(ltos, vtos);

  __ pop_i(Z_ARG3);
  __ pop_ptr(Z_tmp_2);
  // Z_tos   : value
  // Z_ARG3  : index
  // Z_tmp_2 : array
 index_check(Z_tmp_2, Z_ARG3, LogBytesPerLong); // Prefer index in Z_ARG3.
  __ reg2mem_opt(Z_tos,
                 Address(Z_tmp_2, Z_ARG3, arrayOopDesc::base_offset_in_bytes(T_LONG)));
}

void TemplateTable::fastore() {
  transition(ftos, vtos);

  __ pop_i(Z_ARG3);
  __ pop_ptr(Z_tmp_2);
  // Z_ftos  : value
  // Z_ARG3  : index
  // Z_tmp_2 : array
  index_check(Z_tmp_2, Z_ARG3, LogBytesPerInt); // Prefer index in Z_ARG3.
  __ freg2mem_opt(Z_ftos,
                  Address(Z_tmp_2, Z_ARG3, arrayOopDesc::base_offset_in_bytes(T_FLOAT)),
                  false);
}

void TemplateTable::dastore() {
  transition(dtos, vtos);

  __ pop_i(Z_ARG3);
  __ pop_ptr(Z_tmp_2);
  // Z_ftos  : value
  // Z_ARG3  : index
  // Z_tmp_2 : array
  index_check(Z_tmp_2, Z_ARG3, LogBytesPerLong); // Prefer index in Z_ARG3.
  __ freg2mem_opt(Z_ftos,
                  Address(Z_tmp_2, Z_ARG3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)));
}

void TemplateTable::aastore() {
  NearLabel is_null, ok_is_subtype, done;
  transition(vtos, vtos);

  // stack: ..., array, index, value

  Register Rvalue = Z_tos;
  Register Rarray = Z_ARG2;
  Register Rindex = Z_ARG3; // Convention for index_check().

  __ load_ptr(0, Rvalue);
  __ z_l(Rindex, Address(Z_esp, Interpreter::expr_offset_in_bytes(1)));
  __ load_ptr(2, Rarray);

  unsigned const int shift = LogBytesPerHeapOop;
  index_check(Rarray, Rindex, shift); // side effect: Rindex = Rindex << shift
  Register Rstore_addr  = Rindex;
  // Address where the store goes to, i.e. &(Rarry[index])
  __ load_address(Rstore_addr, Address(Rarray, Rindex, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));

  // do array store check - check for null value first.
  __ compareU64_and_branch(Rvalue, (intptr_t)0, Assembler::bcondEqual, is_null);

  Register Rsub_klass   = Z_ARG4;
  Register Rsuper_klass = Z_ARG5;
  __ load_klass(Rsub_klass, Rvalue);
  // Load superklass.
  __ load_klass(Rsuper_klass, Rarray);
  __ z_lg(Rsuper_klass, Address(Rsuper_klass, ObjArrayKlass::element_klass_offset()));

  // Generate a fast subtype check.  Branch to ok_is_subtype if no failure.
  // Throw if failure.
  Register tmp1 = Z_tmp_1;
  Register tmp2 = Z_tmp_2;
  __ gen_subtype_check(Rsub_klass, Rsuper_klass, tmp1, tmp2, ok_is_subtype);

  // Fall through on failure.
  // Object is in Rvalue == Z_tos.
  assert(Rvalue == Z_tos, "that's the expected location");
  __ load_absolute_address(tmp1, Interpreter::_throw_ArrayStoreException_entry);
  __ z_br(tmp1);

  Register tmp3 = Rsub_klass;

  // Have a null in Rvalue.
  __ bind(is_null);
  __ profile_null_seen(tmp1);

  // Store a null.
  do_oop_store(_masm, Address(Rstore_addr, (intptr_t)0), noreg,
               tmp3, tmp2, tmp1, IS_ARRAY);
  __ z_bru(done);

  // Come here on success.
  __ bind(ok_is_subtype);

  // Now store using the appropriate barrier.
  do_oop_store(_masm, Address(Rstore_addr, (intptr_t)0), Rvalue,
               tmp3, tmp2, tmp1, IS_ARRAY | IS_NOT_NULL);

  // Pop stack arguments.
  __ bind(done);
  __ add2reg(Z_esp, 3 * Interpreter::stackElementSize);
}


void TemplateTable::bastore() {
  transition(itos, vtos);

  __ pop_i(Z_ARG3);
  __ pop_ptr(Z_tmp_2);
  // Z_tos   : value
  // Z_ARG3  : index
  // Z_tmp_2 : array

  // Need to check whether array is boolean or byte
  // since both types share the bastore bytecode.
  __ load_klass(Z_tmp_1, Z_tmp_2);
  __ z_llgf(Z_tmp_1, Address(Z_tmp_1, Klass::layout_helper_offset()));
  __ z_tmll(Z_tmp_1, Klass::layout_helper_boolean_diffbit());
  Label L_skip;
  __ z_bfalse(L_skip);
  // if it is a T_BOOLEAN array, mask the stored value to 0/1
  __ z_nilf(Z_tos, 0x1);
  __ bind(L_skip);

  // No index shift necessary - pass 0.
  index_check(Z_tmp_2, Z_ARG3, 0); // Prefer index in Z_ARG3.
  __ z_stc(Z_tos,
           Address(Z_tmp_2, Z_ARG3, arrayOopDesc::base_offset_in_bytes(T_BYTE)));
}

void TemplateTable::castore() {
  transition(itos, vtos);

  __ pop_i(Z_ARG3);
  __ pop_ptr(Z_tmp_2);
  // Z_tos   : value
  // Z_ARG3  : index
  // Z_tmp_2 : array
  Register index = Z_ARG3; // prefer index in Z_ARG3
  index_check(Z_tmp_2, index, LogBytesPerShort);
  __ z_sth(Z_tos,
           Address(Z_tmp_2, index, arrayOopDesc::base_offset_in_bytes(T_CHAR)));
}

void TemplateTable::sastore() {
  castore();
}

void TemplateTable::istore(int n) {
  transition(itos, vtos);
  __ reg2mem_opt(Z_tos, iaddress(n), false);
}

void TemplateTable::lstore(int n) {
  transition(ltos, vtos);
  __ reg2mem_opt(Z_tos, laddress(n));
}

void TemplateTable::fstore(int n) {
  transition(ftos, vtos);
  __ freg2mem_opt(Z_ftos, faddress(n), false);
}

void TemplateTable::dstore(int n) {
  transition(dtos, vtos);
  __ freg2mem_opt(Z_ftos, daddress(n));
}

void TemplateTable::astore(int n) {
  transition(vtos, vtos);
  __ pop_ptr(Z_tos);
  __ reg2mem_opt(Z_tos, aaddress(n));
}

void TemplateTable::pop() {
  transition(vtos, vtos);
  __ add2reg(Z_esp, Interpreter::stackElementSize);
}

void TemplateTable::pop2() {
  transition(vtos, vtos);
  __ add2reg(Z_esp, 2 * Interpreter::stackElementSize);
}

void TemplateTable::dup() {
  transition(vtos, vtos);
  __ load_ptr(0, Z_tos);
  __ push_ptr(Z_tos);
  // stack: ..., a, a
}

void TemplateTable::dup_x1() {
  transition(vtos, vtos);

  // stack: ..., a, b
  __ load_ptr(0, Z_tos);          // load b
  __ load_ptr(1, Z_R0_scratch);   // load a
  __ store_ptr(1, Z_tos);         // store b
  __ store_ptr(0, Z_R0_scratch);  // store a
  __ push_ptr(Z_tos);             // push b
  // stack: ..., b, a, b
}

void TemplateTable::dup_x2() {
  transition(vtos, vtos);

  // stack: ..., a, b, c
  __ load_ptr(0, Z_R0_scratch);   // load c
  __ load_ptr(2, Z_R1_scratch);   // load a
  __ store_ptr(2, Z_R0_scratch);  // store c in a
  __ push_ptr(Z_R0_scratch);      // push c
  // stack: ..., c, b, c, c
  __ load_ptr(2, Z_R0_scratch);   // load b
  __ store_ptr(2, Z_R1_scratch);  // store a in b
  // stack: ..., c, a, c, c
  __ store_ptr(1, Z_R0_scratch);  // store b in c
  // stack: ..., c, a, b, c
}

void TemplateTable::dup2() {
  transition(vtos, vtos);

  // stack: ..., a, b
  __ load_ptr(1, Z_R0_scratch);  // load a
  __ push_ptr(Z_R0_scratch);     // push a
  __ load_ptr(1, Z_R0_scratch);  // load b
  __ push_ptr(Z_R0_scratch);     // push b
  // stack: ..., a, b, a, b
}

void TemplateTable::dup2_x1() {
  transition(vtos, vtos);

  // stack: ..., a, b, c
  __ load_ptr(0, Z_R0_scratch);  // load c
  __ load_ptr(1, Z_R1_scratch);  // load b
  __ push_ptr(Z_R1_scratch);     // push b
  __ push_ptr(Z_R0_scratch);     // push c
  // stack: ..., a, b, c, b, c
  __ store_ptr(3, Z_R0_scratch); // store c in b
  // stack: ..., a, c, c, b, c
  __ load_ptr( 4, Z_R0_scratch); // load a
  __ store_ptr(2, Z_R0_scratch); // store a in 2nd c
  // stack: ..., a, c, a, b, c
  __ store_ptr(4, Z_R1_scratch); // store b in a
  // stack: ..., b, c, a, b, c
}

void TemplateTable::dup2_x2() {
  transition(vtos, vtos);

  // stack: ..., a, b, c, d
  __ load_ptr(0, Z_R0_scratch);   // load d
  __ load_ptr(1, Z_R1_scratch);   // load c
  __ push_ptr(Z_R1_scratch);      // push c
  __ push_ptr(Z_R0_scratch);      // push d
  // stack: ..., a, b, c, d, c, d
  __ load_ptr(4, Z_R1_scratch);   // load b
  __ store_ptr(2, Z_R1_scratch);  // store b in d
  __ store_ptr(4, Z_R0_scratch);  // store d in b
  // stack: ..., a, d, c, b, c, d
  __ load_ptr(5, Z_R0_scratch);   // load a
  __ load_ptr(3, Z_R1_scratch);   // load c
  __ store_ptr(3, Z_R0_scratch);  // store a in c
  __ store_ptr(5, Z_R1_scratch);  // store c in a
  // stack: ..., c, d, a, b, c, d
}

void TemplateTable::swap() {
  transition(vtos, vtos);

  // stack: ..., a, b
  __ load_ptr(1, Z_R0_scratch);  // load a
  __ load_ptr(0, Z_R1_scratch);  // load b
  __ store_ptr(0, Z_R0_scratch);  // store a in b
  __ store_ptr(1, Z_R1_scratch);  // store b in a
  // stack: ..., b, a
}

void TemplateTable::iop2(Operation op) {
  transition(itos, itos);
  switch (op) {
    case add  :                           __ z_ay(Z_tos,  __ stackTop()); __ pop_i(); break;
    case sub  :                           __ z_sy(Z_tos,  __ stackTop()); __ pop_i(); __ z_lcr(Z_tos, Z_tos); break;
    case mul  :                           __ z_msy(Z_tos, __ stackTop()); __ pop_i(); break;
    case _and :                           __ z_ny(Z_tos,  __ stackTop()); __ pop_i(); break;
    case _or  :                           __ z_oy(Z_tos,  __ stackTop()); __ pop_i(); break;
    case _xor :                           __ z_xy(Z_tos,  __ stackTop()); __ pop_i(); break;
    case shl  : __ z_lr(Z_tmp_1, Z_tos);
                __ z_nill(Z_tmp_1, 31);  // Lowest 5 bits are shiftamount.
                                          __ pop_i(Z_tos);   __ z_sll(Z_tos, 0,  Z_tmp_1); break;
    case shr  : __ z_lr(Z_tmp_1, Z_tos);
                __ z_nill(Z_tmp_1, 31);  // Lowest 5 bits are shiftamount.
                                          __ pop_i(Z_tos);   __ z_sra(Z_tos, 0,  Z_tmp_1); break;
    case ushr : __ z_lr(Z_tmp_1, Z_tos);
                __ z_nill(Z_tmp_1, 31);  // Lowest 5 bits are shiftamount.
                                          __ pop_i(Z_tos);   __ z_srl(Z_tos, 0,  Z_tmp_1); break;
    default   : ShouldNotReachHere(); break;
  }
  return;
}

void TemplateTable::lop2(Operation op) {
  transition(ltos, ltos);

  switch (op) {
    case add  :  __ z_ag(Z_tos,  __ stackTop()); __ pop_l(); break;
    case sub  :  __ z_sg(Z_tos,  __ stackTop()); __ pop_l(); __ z_lcgr(Z_tos, Z_tos); break;
    case mul  :  __ z_msg(Z_tos, __ stackTop()); __ pop_l(); break;
    case _and :  __ z_ng(Z_tos,  __ stackTop()); __ pop_l(); break;
    case _or  :  __ z_og(Z_tos,  __ stackTop()); __ pop_l(); break;
    case _xor :  __ z_xg(Z_tos,  __ stackTop()); __ pop_l(); break;
    default   : ShouldNotReachHere(); break;
  }
  return;
}

// Common part of idiv/irem.
static void idiv_helper(InterpreterMacroAssembler * _masm, address exception) {
  NearLabel not_null;

  // Use register pair Z_tmp_1, Z_tmp_2 for DIVIDE SINGLE.
  assert(Z_tmp_1->successor() == Z_tmp_2, " need even/odd register pair for idiv/irem");

  // Get dividend.
  __ pop_i(Z_tmp_2);

  // If divisor == 0 throw exception.
  __ compare32_and_branch(Z_tos, (intptr_t) 0,
                          Assembler::bcondNotEqual, not_null   );
  __ load_absolute_address(Z_R1_scratch, exception);
  __ z_br(Z_R1_scratch);

  __ bind(not_null);

  __ z_lgfr(Z_tmp_2, Z_tmp_2);   // Sign extend dividend.
  __ z_dsgfr(Z_tmp_1, Z_tos);    // Do it.
}

void TemplateTable::idiv() {
  transition(itos, itos);

  idiv_helper(_masm, Interpreter::_throw_ArithmeticException_entry);
  __ z_llgfr(Z_tos, Z_tmp_2);     // Result is in Z_tmp_2.
}

void TemplateTable::irem() {
  transition(itos, itos);

  idiv_helper(_masm, Interpreter::_throw_ArithmeticException_entry);
  __ z_llgfr(Z_tos, Z_tmp_1);     // Result is in Z_tmp_1.
}

void TemplateTable::lmul() {
  transition(ltos, ltos);

  // Multiply with memory operand.
  __ z_msg(Z_tos, __ stackTop());
  __ pop_l();  // Pop operand.
}

// Common part of ldiv/lrem.
//
// Input:
//     Z_tos := the divisor (dividend still on stack)
//
// Updated registers:
//     Z_tmp_1 := pop_l() % Z_tos     ; if is_ldiv == false
//     Z_tmp_2 := pop_l() / Z_tos     ; if is_ldiv == true
//
static void ldiv_helper(InterpreterMacroAssembler * _masm, address exception, bool is_ldiv) {
  NearLabel not_null, done;

  // Use register pair Z_tmp_1, Z_tmp_2 for DIVIDE SINGLE.
  assert(Z_tmp_1->successor() == Z_tmp_2,
         " need even/odd register pair for idiv/irem");

  // Get dividend.
  __ pop_l(Z_tmp_2);

  // If divisor == 0 throw exception.
  __ compare64_and_branch(Z_tos, (intptr_t)0, Assembler::bcondNotEqual, not_null);
  __ load_absolute_address(Z_R1_scratch, exception);
  __ z_br(Z_R1_scratch);

  __ bind(not_null);
  // Special case for dividend == 0x8000 and divisor == -1.
  if (is_ldiv) {
    // result := Z_tmp_2 := - dividend
    __ z_lcgr(Z_tmp_2, Z_tmp_2);
  } else {
    // result remainder := Z_tmp_1 := 0
    __ clear_reg(Z_tmp_1, true, false);  // Don't set CC.
  }

  // if divisor == -1 goto done
  __ compare64_and_branch(Z_tos, -1, Assembler::bcondEqual, done);
  if (is_ldiv)
    // Restore sign, because divisor != -1.
    __ z_lcgr(Z_tmp_2, Z_tmp_2);
  __ z_dsgr(Z_tmp_1, Z_tos);    // Do it.
  __ bind(done);
}

void TemplateTable::ldiv() {
  transition(ltos, ltos);

  ldiv_helper(_masm, Interpreter::_throw_ArithmeticException_entry, true /*is_ldiv*/);
  __ z_lgr(Z_tos, Z_tmp_2);     // Result is in Z_tmp_2.
}

void TemplateTable::lrem() {
  transition(ltos, ltos);

  ldiv_helper(_masm, Interpreter::_throw_ArithmeticException_entry, false /*is_ldiv*/);
  __ z_lgr(Z_tos, Z_tmp_1);     // Result is in Z_tmp_1.
}

void TemplateTable::lshl() {
  transition(itos, ltos);

  // Z_tos: shift amount
  __ pop_l(Z_tmp_1);              // Get shift value.
  __ z_sllg(Z_tos, Z_tmp_1, 0, Z_tos);
}

void TemplateTable::lshr() {
  transition(itos, ltos);

  // Z_tos: shift amount
  __ pop_l(Z_tmp_1);              // Get shift value.
  __ z_srag(Z_tos, Z_tmp_1, 0, Z_tos);
}

void TemplateTable::lushr() {
  transition(itos, ltos);

  // Z_tos: shift amount
  __ pop_l(Z_tmp_1);              // Get shift value.
  __ z_srlg(Z_tos, Z_tmp_1, 0, Z_tos);
}

void TemplateTable::fop2(Operation op) {
  transition(ftos, ftos);

  switch (op) {
    case add:
      // Add memory operand.
      __ z_aeb(Z_ftos, __ stackTop()); __ pop_f(); return;
    case sub:
      // Sub memory operand.
      __ z_ler(Z_F1, Z_ftos);    // first operand
      __ pop_f(Z_ftos);          // second operand from stack
      __ z_sebr(Z_ftos, Z_F1);
      return;
    case mul:
      // Multiply with memory operand.
      __ z_meeb(Z_ftos, __ stackTop()); __ pop_f(); return;
    case div:
      __ z_ler(Z_F1, Z_ftos);    // first operand
      __ pop_f(Z_ftos);          // second operand from stack
      __ z_debr(Z_ftos, Z_F1);
      return;
    case rem:
      // Do runtime call.
      __ z_ler(Z_FARG2, Z_ftos);  // divisor
      __ pop_f(Z_FARG1);          // dividend
      __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::frem));
      // Result should be in the right place (Z_ftos == Z_FRET).
      return;
    default:
      ShouldNotReachHere();
      return;
  }
}

void TemplateTable::dop2(Operation op) {
  transition(dtos, dtos);

  switch (op) {
    case add:
      // Add memory operand.
      __ z_adb(Z_ftos, __ stackTop()); __ pop_d(); return;
    case sub:
      // Sub memory operand.
      __ z_ldr(Z_F1, Z_ftos);    // first operand
      __ pop_d(Z_ftos);          // second operand from stack
      __ z_sdbr(Z_ftos, Z_F1);
      return;
    case mul:
      // Multiply with memory operand.
      __ z_mdb(Z_ftos, __ stackTop()); __ pop_d(); return;
    case div:
      __ z_ldr(Z_F1, Z_ftos);    // first operand
      __ pop_d(Z_ftos);          // second operand from stack
      __ z_ddbr(Z_ftos, Z_F1);
      return;
    case rem:
      // Do runtime call.
      __ z_ldr(Z_FARG2, Z_ftos);  // divisor
      __ pop_d(Z_FARG1);          // dividend
      __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::drem));
      // Result should be in the right place (Z_ftos == Z_FRET).
      return;
    default:
      ShouldNotReachHere();
      return;
  }
}

void TemplateTable::ineg() {
  transition(itos, itos);
  __ z_lcr(Z_tos);
}

void TemplateTable::lneg() {
  transition(ltos, ltos);
  __ z_lcgr(Z_tos);
}

void TemplateTable::fneg() {
  transition(ftos, ftos);
  __ z_lcebr(Z_ftos, Z_ftos);
}

void TemplateTable::dneg() {
  transition(dtos, dtos);
  __ z_lcdbr(Z_ftos, Z_ftos);
}

void TemplateTable::iinc() {
  transition(vtos, vtos);

  Address local;
  __ z_lb(Z_R0_scratch, at_bcp(2)); // Get constant.
  locals_index(Z_R1_scratch);
  local = iaddress(_masm, Z_R1_scratch);
  __ z_a(Z_R0_scratch, local);
  __ reg2mem_opt(Z_R0_scratch, local, false);
}

void TemplateTable::wide_iinc() {
  transition(vtos, vtos);

  // Z_tmp_1 := increment
  __ get_2_byte_integer_at_bcp(Z_tmp_1, 4, InterpreterMacroAssembler::Signed);
  // Z_R1_scratch := index of local to increment
  locals_index_wide(Z_tmp_2);
  // Load, increment, and store.
  __ access_local_int(Z_tmp_2, Z_tos);
  __ z_agr(Z_tos,  Z_tmp_1);
  // Shifted index is still in Z_tmp_2.
  __ reg2mem_opt(Z_tos, Address(Z_locals, Z_tmp_2), false);
}


void TemplateTable::convert() {
  // Checking
#ifdef ASSERT
  TosState   tos_in  = ilgl;
  TosState   tos_out = ilgl;

  switch (bytecode()) {
    case Bytecodes::_i2l:
    case Bytecodes::_i2f:
    case Bytecodes::_i2d:
    case Bytecodes::_i2b:
    case Bytecodes::_i2c:
    case Bytecodes::_i2s:
      tos_in = itos;
      break;
    case Bytecodes::_l2i:
    case Bytecodes::_l2f:
    case Bytecodes::_l2d:
      tos_in = ltos;
      break;
    case Bytecodes::_f2i:
    case Bytecodes::_f2l:
    case Bytecodes::_f2d:
      tos_in = ftos;
      break;
    case Bytecodes::_d2i:
    case Bytecodes::_d2l:
    case Bytecodes::_d2f:
      tos_in = dtos;
      break;
    default :
      ShouldNotReachHere();
  }
  switch (bytecode()) {
    case Bytecodes::_l2i:
    case Bytecodes::_f2i:
    case Bytecodes::_d2i:
    case Bytecodes::_i2b:
    case Bytecodes::_i2c:
    case Bytecodes::_i2s:
      tos_out = itos;
      break;
    case Bytecodes::_i2l:
    case Bytecodes::_f2l:
    case Bytecodes::_d2l:
      tos_out = ltos;
      break;
    case Bytecodes::_i2f:
    case Bytecodes::_l2f:
    case Bytecodes::_d2f:
      tos_out = ftos;
      break;
    case Bytecodes::_i2d:
    case Bytecodes::_l2d:
    case Bytecodes::_f2d:
      tos_out = dtos;
      break;
    default :
      ShouldNotReachHere();
  }

  transition(tos_in, tos_out);
#endif // ASSERT

  // Conversion
  Label done;
  switch (bytecode()) {
    case Bytecodes::_i2l:
      __ z_lgfr(Z_tos, Z_tos);
      return;
    case Bytecodes::_i2f:
      __ z_cefbr(Z_ftos, Z_tos);
      return;
    case Bytecodes::_i2d:
      __ z_cdfbr(Z_ftos, Z_tos);
      return;
    case Bytecodes::_i2b:
      // Sign extend least significant byte.
      __ move_reg_if_needed(Z_tos, T_BYTE, Z_tos, T_INT);
      return;
    case Bytecodes::_i2c:
      // Zero extend 2 least significant bytes.
      __ move_reg_if_needed(Z_tos, T_CHAR, Z_tos, T_INT);
      return;
    case Bytecodes::_i2s:
      // Sign extend 2 least significant bytes.
      __ move_reg_if_needed(Z_tos, T_SHORT, Z_tos, T_INT);
      return;
    case Bytecodes::_l2i:
      // Sign-extend not needed here, upper 4 bytes of int value in register are ignored.
      return;
    case Bytecodes::_l2f:
      __ z_cegbr(Z_ftos, Z_tos);
      return;
    case Bytecodes::_l2d:
      __ z_cdgbr(Z_ftos, Z_tos);
      return;
    case Bytecodes::_f2i:
    case Bytecodes::_f2l:
      __ clear_reg(Z_tos, true, false);  // Don't set CC.
      __ z_cebr(Z_ftos, Z_ftos);
      __ z_brno(done); // NaN -> 0
      if (bytecode() == Bytecodes::_f2i)
        __ z_cfebr(Z_tos, Z_ftos, Assembler::to_zero);
      else // bytecode() == Bytecodes::_f2l
        __ z_cgebr(Z_tos, Z_ftos, Assembler::to_zero);
      break;
    case Bytecodes::_f2d:
      __ move_freg_if_needed(Z_ftos, T_DOUBLE, Z_ftos, T_FLOAT);
      return;
    case Bytecodes::_d2i:
    case Bytecodes::_d2l:
      __ clear_reg(Z_tos, true, false);  // Ddon't set CC.
      __ z_cdbr(Z_ftos, Z_ftos);
      __ z_brno(done); // NaN -> 0
      if (bytecode() == Bytecodes::_d2i)
        __ z_cfdbr(Z_tos, Z_ftos, Assembler::to_zero);
      else // Bytecodes::_d2l
        __ z_cgdbr(Z_tos, Z_ftos, Assembler::to_zero);
      break;
    case Bytecodes::_d2f:
      __ move_freg_if_needed(Z_ftos, T_FLOAT, Z_ftos, T_DOUBLE);
      return;
    default:
      ShouldNotReachHere();
  }
  __ bind(done);
}

void TemplateTable::lcmp() {
  transition(ltos, itos);

  Label   done;
  Register val1 = Z_R0_scratch;
  Register val2 = Z_R1_scratch;

  if (VM_Version::has_LoadStoreConditional()) {
    __ pop_l(val1);           // pop value 1.
    __ z_lghi(val2,  -1);     // lt value
    __ z_cgr(val1, Z_tos);    // Compare with Z_tos (value 2). Protect CC under all circumstances.
    __ z_lghi(val1,   1);     // gt value
    __ z_lghi(Z_tos,  0);     // eq value

    __ z_locgr(Z_tos, val1, Assembler::bcondHigh);
    __ z_locgr(Z_tos, val2, Assembler::bcondLow);
  } else {
    __ pop_l(val1);           // Pop value 1.
    __ z_cgr(val1, Z_tos);    // Compare with Z_tos (value 2). Protect CC under all circumstances.

    __ z_lghi(Z_tos,  0);     // eq value
    __ z_bre(done);

    __ z_lghi(Z_tos,  1);     // gt value
    __ z_brh(done);

    __ z_lghi(Z_tos, -1);     // lt value
  }

  __ bind(done);
}


void TemplateTable::float_cmp(bool is_float, int unordered_result) {
  Label done;

  if (is_float) {
    __ pop_f(Z_FARG2);
    __ z_cebr(Z_FARG2, Z_ftos);
  } else {
    __ pop_d(Z_FARG2);
    __ z_cdbr(Z_FARG2, Z_ftos);
  }

  if (VM_Version::has_LoadStoreConditional()) {
    Register one       = Z_R0_scratch;
    Register minus_one = Z_R1_scratch;
    __ z_lghi(minus_one,  -1);
    __ z_lghi(one,  1);
    __ z_lghi(Z_tos, 0);
    __ z_locgr(Z_tos, one,       unordered_result == 1 ? Assembler::bcondHighOrNotOrdered : Assembler::bcondHigh);
    __ z_locgr(Z_tos, minus_one, unordered_result == 1 ? Assembler::bcondLow              : Assembler::bcondLowOrNotOrdered);
  } else {
    // Z_FARG2 == Z_ftos
    __ clear_reg(Z_tos, false, false);
    __ z_bre(done);

    // F_ARG2 > Z_Ftos, or unordered
    __ z_lhi(Z_tos, 1);
    __ z_brc(unordered_result == 1 ? Assembler::bcondHighOrNotOrdered : Assembler::bcondHigh, done);

    // F_ARG2 < Z_FTOS, or unordered
    __ z_lhi(Z_tos, -1);

    __ bind(done);
  }
}

void TemplateTable::branch(bool is_jsr, bool is_wide) {
  const Register   bumped_count = Z_tmp_1;
  const Register   method       = Z_tmp_2;
  const Register   m_counters   = Z_R1_scratch;
  const Register   mdo          = Z_tos;

  BLOCK_COMMENT("TemplateTable::branch {");
  __ get_method(method);
  __ profile_taken_branch(mdo, bumped_count);

  const ByteSize ctr_offset = InvocationCounter::counter_offset();
  const ByteSize be_offset  = MethodCounters::backedge_counter_offset()   + ctr_offset;
  const ByteSize inv_offset = MethodCounters::invocation_counter_offset() + ctr_offset;

  // Get (wide) offset to disp.
  const Register disp = Z_ARG5;
  if (is_wide) {
    __ get_4_byte_integer_at_bcp(disp, 1);
  } else {
    __ get_2_byte_integer_at_bcp(disp, 1, InterpreterMacroAssembler::Signed);
  }

  // Handle all the JSR stuff here, then exit.
  // It's much shorter and cleaner than intermingling with the
  // non-JSR normal-branch stuff occurring below.
  if (is_jsr) {
    // Compute return address as bci in Z_tos.
    __ z_lgr(Z_R1_scratch, Z_bcp);
    __ z_sg(Z_R1_scratch, Address(method, Method::const_offset()));
    __ add2reg(Z_tos, (is_wide ? 5 : 3) - in_bytes(ConstMethod::codes_offset()), Z_R1_scratch);

    // Bump bcp to target of JSR.
    __ z_agr(Z_bcp, disp);
    // Push return address for "ret" on stack.
    __ push_ptr(Z_tos);
    // And away we go!
    __ dispatch_next(vtos, 0 , true);
    return;
  }

  // Normal (non-jsr) branch handling.

  // Bump bytecode pointer by displacement (take the branch).
  __ z_agr(Z_bcp, disp);

  assert(UseLoopCounter || !UseOnStackReplacement,
         "on-stack-replacement requires loop counters");

  NearLabel backedge_counter_overflow;
  NearLabel dispatch;
  int       increment = InvocationCounter::count_increment;

  if (UseLoopCounter) {
    // Increment backedge counter for backward branches.
    // disp: target offset
    // Z_bcp: target bcp
    // Z_locals: locals pointer
    //
    // Count only if backward branch.
    __ compare32_and_branch(disp, (intptr_t)0, Assembler::bcondHigh, dispatch);


    if (ProfileInterpreter) {
      NearLabel   no_mdo;

      // Are we profiling?
      __ load_and_test_long(mdo, Address(method, Method::method_data_offset()));
      __ branch_optimized(Assembler::bcondZero, no_mdo);

      // Increment the MDO backedge counter.
      const Address mdo_backedge_counter(mdo, MethodData::backedge_counter_offset() + InvocationCounter::counter_offset());

      const Address mask(mdo, MethodData::backedge_mask_offset());
      __ increment_mask_and_jump(mdo_backedge_counter, increment, mask,
                                 Z_ARG2, false, Assembler::bcondZero,
                                 UseOnStackReplacement ? &backedge_counter_overflow : nullptr);
      __ z_bru(dispatch);
      __ bind(no_mdo);
    }

    // Increment backedge counter in MethodCounters*.
    __ get_method_counters(method, m_counters, dispatch);
    const Address mask(m_counters, MethodCounters::backedge_mask_offset());
    __ increment_mask_and_jump(Address(m_counters, be_offset),
                               increment, mask,
                               Z_ARG2, false, Assembler::bcondZero,
                               UseOnStackReplacement ? &backedge_counter_overflow : nullptr);
    __ bind(dispatch);
  }

  // Pre-load the next target bytecode into rbx.
  __ z_llgc(Z_bytecode, Address(Z_bcp, (intptr_t) 0));

  // Continue with the bytecode @ target.
  // Z_tos: Return bci for jsr's, unused otherwise.
  // Z_bytecode: target bytecode
  // Z_bcp: target bcp
  __ dispatch_only(vtos, true);

  // Out-of-line code runtime calls.
  if (UseLoopCounter && UseOnStackReplacement) {
    // invocation counter overflow
    __ bind(backedge_counter_overflow);

    __ z_lcgr(Z_ARG2, disp); // Z_ARG2 := -disp
    __ z_agr(Z_ARG2, Z_bcp); // Z_ARG2 := branch target bcp - disp == branch bcp
    __ call_VM(noreg,
               CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow),
               Z_ARG2);

    // Z_RET: osr nmethod (osr ok) or null (osr not possible).
    __ compare64_and_branch(Z_RET, (intptr_t) 0, Assembler::bcondEqual, dispatch);

    // Nmethod may have been invalidated (VM may block upon call_VM return).
    __ z_cliy(in_bytes(nmethod::state_offset()), Z_RET, nmethod::in_use);
    __ z_brne(dispatch);

    // Migrate the interpreter frame off of the stack.

    __ z_lgr(Z_tmp_1, Z_RET); // Save the nmethod.

    call_VM(noreg,
            CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_begin));

    // Z_RET is OSR buffer, move it to expected parameter location.
    __ lgr_if_needed(Z_ARG1, Z_RET);

    // Pop the interpreter frame ...
    __ pop_interpreter_frame(Z_R14, Z_ARG2/*tmp1*/, Z_ARG3/*tmp2*/);

    // ... and begin the OSR nmethod.
    __ z_lg(Z_R1_scratch, Address(Z_tmp_1, nmethod::osr_entry_point_offset()));
    __ z_br(Z_R1_scratch);
  }
  BLOCK_COMMENT("} TemplateTable::branch");
}

void TemplateTable::if_0cmp(Condition cc) {
  transition(itos, vtos);

  // Assume branch is more often taken than not (loops use backward branches).
  NearLabel not_taken;
  __ compare32_and_branch(Z_tos, (intptr_t) 0, j_not(cc), not_taken);
  branch(false, false);
  __ bind(not_taken);
  __ profile_not_taken_branch(Z_tos);
}

void TemplateTable::if_icmp(Condition cc) {
  transition(itos, vtos);

  // Assume branch is more often taken than not (loops use backward branches).
  NearLabel not_taken;
  __ pop_i(Z_R0_scratch);
  __ compare32_and_branch(Z_R0_scratch, Z_tos, j_not(cc), not_taken);
  branch(false, false);
  __ bind(not_taken);
  __ profile_not_taken_branch(Z_tos);
}

void TemplateTable::if_nullcmp(Condition cc) {
  transition(atos, vtos);

  // Assume branch is more often taken than not (loops use backward branches) .
  NearLabel not_taken;
  __ compare64_and_branch(Z_tos, (intptr_t) 0, j_not(cc), not_taken);
  branch(false, false);
  __ bind(not_taken);
  __ profile_not_taken_branch(Z_tos);
}

void TemplateTable::if_acmp(Condition cc) {
  transition(atos, vtos);
  // Assume branch is more often taken than not (loops use backward branches).
  NearLabel not_taken;
  __ pop_ptr(Z_ARG2);
  __ verify_oop(Z_ARG2);
  __ verify_oop(Z_tos);
  __ compareU64_and_branch(Z_tos, Z_ARG2, j_not(cc), not_taken);
  branch(false, false);
  __ bind(not_taken);
  __ profile_not_taken_branch(Z_ARG3);
}

void TemplateTable::ret() {
  transition(vtos, vtos);

  locals_index(Z_tmp_1);
  // Get return bci, compute return bcp. Must load 64 bits.
  __ mem2reg_opt(Z_tmp_1, iaddress(_masm, Z_tmp_1));
  __ profile_ret(Z_tmp_1, Z_tmp_2);
  __ get_method(Z_tos);
  __ mem2reg_opt(Z_R1_scratch, Address(Z_tos, Method::const_offset()));
  __ load_address(Z_bcp, Address(Z_R1_scratch, Z_tmp_1, ConstMethod::codes_offset()));
  __ dispatch_next(vtos, 0 , true);
}

void TemplateTable::wide_ret() {
  transition(vtos, vtos);

  locals_index_wide(Z_tmp_1);
  // Get return bci, compute return bcp.
  __ mem2reg_opt(Z_tmp_1, aaddress(_masm, Z_tmp_1));
  __ profile_ret(Z_tmp_1, Z_tmp_2);
  __ get_method(Z_tos);
  __ mem2reg_opt(Z_R1_scratch, Address(Z_tos, Method::const_offset()));
  __ load_address(Z_bcp, Address(Z_R1_scratch, Z_tmp_1, ConstMethod::codes_offset()));
  __ dispatch_next(vtos, 0, true);
}

void TemplateTable::tableswitch () {
  transition(itos, vtos);

  NearLabel default_case, continue_execution;
  Register  bcp = Z_ARG5;
  // Align bcp.
  __ load_address(bcp, at_bcp(BytesPerInt));
  __ z_nill(bcp, (-BytesPerInt) & 0xffff);

  // Load lo & hi.
  Register low  = Z_tmp_1;
  Register high = Z_tmp_2;

  // Load low into 64 bits, since used for address calculation.
  __ mem2reg_signed_opt(low, Address(bcp, BytesPerInt));
  __ mem2reg_opt(high, Address(bcp, 2 * BytesPerInt), false);
  // Sign extend "label" value for address calculation.
  __ z_lgfr(Z_tos, Z_tos);

  // Check against lo & hi.
  __ compare32_and_branch(Z_tos, low, Assembler::bcondLow, default_case);
  __ compare32_and_branch(Z_tos, high, Assembler::bcondHigh, default_case);

  // Lookup dispatch offset.
  __ z_sgr(Z_tos, low);
  Register jump_table_offset = Z_ARG3;
  // Index2offset; index in Z_tos is killed by profile_switch_case.
  __ z_sllg(jump_table_offset, Z_tos, LogBytesPerInt);
  __ profile_switch_case(Z_tos, Z_ARG4 /*tmp for mdp*/, low/*tmp*/, Z_bytecode/*tmp*/);

  Register index = Z_tmp_2;

  // Load index sign extended for addressing.
  __ mem2reg_signed_opt(index, Address(bcp, jump_table_offset, 3 * BytesPerInt));

  // Continue execution.
  __ bind(continue_execution);

  // Load next bytecode.
  __ z_llgc(Z_bytecode, Address(Z_bcp, index));
  __ z_agr(Z_bcp, index); // Advance bcp.
  __ dispatch_only(vtos, true);

  // Handle default.
  __ bind(default_case);

  __ profile_switch_default(Z_tos);
  __ mem2reg_signed_opt(index, Address(bcp));
  __ z_bru(continue_execution);
}

void TemplateTable::lookupswitch () {
  transition(itos, itos);
  __ stop("lookupswitch bytecode should have been rewritten");
}

void TemplateTable::fast_linearswitch () {
  transition(itos, vtos);

  Label    loop_entry, loop, found, continue_execution;
  Register bcp = Z_ARG5;

  // Align bcp.
  __ load_address(bcp, at_bcp(BytesPerInt));
  __ z_nill(bcp, (-BytesPerInt) & 0xffff);

  // Start search with last case.
  Register current_case_offset = Z_tmp_1;

  __ mem2reg_signed_opt(current_case_offset, Address(bcp, BytesPerInt));
  __ z_sllg(current_case_offset, current_case_offset, LogBytesPerWord);   // index2bytes
  __ z_bru(loop_entry);

  // table search
  __ bind(loop);

  __ z_c(Z_tos, Address(bcp, current_case_offset, 2 * BytesPerInt));
  __ z_bre(found);

  __ bind(loop_entry);
  __ z_aghi(current_case_offset, -2 * BytesPerInt);  // Decrement.
  __ z_brnl(loop);

  // default case
  Register   offset = Z_tmp_2;

  __ profile_switch_default(Z_tos);
  // Load offset sign extended for addressing.
  __ mem2reg_signed_opt(offset, Address(bcp));
  __ z_bru(continue_execution);

  // Entry found -> get offset.
  __ bind(found);
  __ mem2reg_signed_opt(offset, Address(bcp, current_case_offset, 3 * BytesPerInt));
  // Profile that this case was taken.
  Register current_case_idx = Z_ARG4;
  __ z_srlg(current_case_idx, current_case_offset, LogBytesPerWord); // bytes2index
  __ profile_switch_case(current_case_idx, Z_tos, bcp, Z_bytecode);

  // Continue execution.
  __ bind(continue_execution);

  // Load next bytecode.
  __ z_llgc(Z_bytecode, Address(Z_bcp, offset, 0));
  __ z_agr(Z_bcp, offset); // Advance bcp.
  __ dispatch_only(vtos, true);
}


void TemplateTable::fast_binaryswitch() {

  transition(itos, vtos);

  // Implementation using the following core algorithm:
  //
  // int binary_search(int key, LookupswitchPair* array, int n) {
  //   // Binary search according to "Methodik des Programmierens" by
  //   // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
  //   int i = 0;
  //   int j = n;
  //   while (i+1 < j) {
  //     // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
  //     // with      Q: for all i: 0 <= i < n: key < a[i]
  //     // where a stands for the array and assuming that the (inexisting)
  //     // element a[n] is infinitely big.
  //     int h = (i + j) >> 1;
  //     // i < h < j
  //     if (key < array[h].fast_match()) {
  //       j = h;
  //     } else {
  //       i = h;
  //     }
  //   }
  //   // R: a[i] <= key < a[i+1] or Q
  //   // (i.e., if key is within array, i is the correct index)
  //   return i;
  // }

  // Register allocation
  // Note: Since we use the indices in address operands, we do all the
  // computation in 64 bits.
  const Register key   = Z_tos; // Already set (tosca).
  const Register array = Z_tmp_1;
  const Register i     = Z_tmp_2;
  const Register j     = Z_ARG5;
  const Register h     = Z_ARG4;
  const Register temp  = Z_R1_scratch;

  // Find array start.
  __ load_address(array, at_bcp(3 * BytesPerInt));
  __ z_nill(array, (-BytesPerInt) & 0xffff);   // align

  // Initialize i & j.
  __ clear_reg(i, true, false);  // i = 0;  Don't set CC.
  __ mem2reg_signed_opt(j, Address(array, -BytesPerInt)); // j = length(array);

  // And start.
  Label entry;
  __ z_bru(entry);

  // binary search loop
  {
    NearLabel   loop;

    __ bind(loop);

    // int h = (i + j) >> 1;
    __ add2reg_with_index(h, 0, i, j); // h = i + j;
    __ z_srag(h, h, 1);                // h = (i + j) >> 1;

    // if (key < array[h].fast_match()) {
    //   j = h;
    // } else {
    //   i = h;
    // }

    // Convert array[h].match to native byte-ordering before compare.
    __ z_sllg(temp, h, LogBytesPerWord);   // index2bytes
    __ mem2reg_opt(temp, Address(array, temp), false);

    NearLabel  else_;

    __ compare32_and_branch(key, temp, Assembler::bcondNotLow, else_);
    // j = h if (key <  array[h].fast_match())
    __ z_lgr(j, h);
    __ z_bru(entry); // continue

    __ bind(else_);

    // i = h if (key >= array[h].fast_match())
    __ z_lgr(i, h);  // and fallthrough

    // while (i+1 < j)
    __ bind(entry);

    // if (i + 1 < j) continue search
    __ add2reg(h, 1, i);
    __ compare64_and_branch(h, j, Assembler::bcondLow, loop);
  }

  // End of binary search, result index is i (must check again!).
  NearLabel default_case;

  // h is no longer needed, so use it to hold the byte offset.
  __ z_sllg(h, i, LogBytesPerWord);   // index2bytes
  __ mem2reg_opt(temp, Address(array, h), false);
  __ compare32_and_branch(key, temp, Assembler::bcondNotEqual, default_case);

  // entry found -> j = offset
  __ mem2reg_signed_opt(j, Address(array, h, BytesPerInt));
  __ profile_switch_case(i, key, array, Z_bytecode);
  // Load next bytecode.
  __ z_llgc(Z_bytecode, Address(Z_bcp, j));
  __ z_agr(Z_bcp, j);       // Advance bcp.
  __ dispatch_only(vtos, true);

  // default case -> j = default offset
  __ bind(default_case);

  __ profile_switch_default(i);
  __ mem2reg_signed_opt(j, Address(array, -2 * BytesPerInt));
  // Load next bytecode.
  __ z_llgc(Z_bytecode, Address(Z_bcp, j));
  __ z_agr(Z_bcp, j);       // Advance bcp.
  __ dispatch_only(vtos, true);
}

void TemplateTable::_return(TosState state) {
  transition(state, state);
  assert(_desc->calls_vm(),
         "inconsistent calls_vm information"); // call in remove_activation

  if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
    Register Rthis  = Z_ARG2;
    Register Rklass = Z_ARG5;
    Label skip_register_finalizer;
    assert(state == vtos, "only valid state");
    __ z_lg(Rthis, aaddress(0));
    __ load_klass(Rklass, Rthis);
    __ z_tm(Address(Rklass, Klass::misc_flags_offset()), KlassFlags::_misc_has_finalizer);
    __ z_bfalse(skip_register_finalizer);
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), Rthis);
    __ bind(skip_register_finalizer);
  }

  if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
    Label no_safepoint;
    const Address poll_byte_addr(Z_thread, in_bytes(JavaThread::polling_word_offset()) + 7 /* Big Endian */);
    __ z_tm(poll_byte_addr, SafepointMechanism::poll_bit());
    __ z_braz(no_safepoint);
    __ push(state);
    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint));
    __ pop(state);
    __ bind(no_safepoint);
  }

  if (state == itos) {
    // Narrow result if state is itos but result type is smaller.
    // Need to narrow in the return bytecode rather than in generate_return_entry
    // since compiled code callers expect the result to already be narrowed.
    __ narrow(Z_tos, Z_tmp_1); /* fall through */
  }

  __ remove_activation(state, Z_R14);
  __ z_br(Z_R14);
}

// ----------------------------------------------------------------------------
// Register Killed: Z_R1_scratch
void TemplateTable::resolve_cache_and_index_for_method(int byte_no,
                                                       Register Rcache,
                                                       Register index) {
  BLOCK_COMMENT("resolve_cache_and_index_for_method {");
  assert_different_registers(Rcache, index);
  assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");

  Label resolved, clinit_barrier_slow;

  Bytecodes::Code code = bytecode();
  switch (code) {
    case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
    case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
    default:
      break;
  }

  const int bc_offset = (byte_no == f1_byte) ? in_bytes(ResolvedMethodEntry::bytecode1_offset())
                                             : in_bytes(ResolvedMethodEntry::bytecode2_offset());

  __ load_method_entry(Rcache, index);
  __ z_cli(Address(Rcache, bc_offset), code);
  __ z_bre(resolved);

  // Resolve first time through
  // Class initialization barrier slow path lands here as well.
  __ bind(clinit_barrier_slow);
  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
  __ load_const_optimized(Z_ARG2, (int)code);
  __ call_VM(noreg, entry, Z_ARG2);

  // Update registers with resolved info.
  __ load_method_entry(Rcache, index);
  __ bind(resolved);

  // Class initialization barrier for static methods
  if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
    const Register method = Z_R1_scratch;
    const Register klass  = Z_R1_scratch;
    __ z_lg(method, Address(Rcache, in_bytes(ResolvedMethodEntry::method_offset())));
    __ load_method_holder(klass, method);
    __ clinit_barrier(klass, Z_thread, nullptr /*L_fast_path*/, &clinit_barrier_slow);
  }

  BLOCK_COMMENT("} resolve_cache_and_index_for_method");
}

void TemplateTable::resolve_cache_and_index_for_field(int byte_no,
                                                      Register cache,
                                                      Register index) {
  BLOCK_COMMENT("resolve_cache_and_index_for_field {");

  assert_different_registers(cache, index);
  assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");

  NearLabel resolved;

  Bytecodes::Code code = bytecode();
  switch (code) {
    case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
    case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
    default: break;
  }

  __ load_field_entry(cache, index);
  const int code_offset = (byte_no == f1_byte) ? in_bytes(ResolvedFieldEntry::get_code_offset()) :
                                                 in_bytes(ResolvedFieldEntry::put_code_offset()) ;

  __ z_cli(Address(cache, code_offset), code);
  __ z_bre(resolved);

  // resolve first time through
  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
  __ load_const_optimized(Z_ARG2, (int)code);
  __ call_VM(noreg, entry, Z_ARG2);

  // Update registers with resolved info.
  __ load_field_entry(cache, index);

  __ bind(resolved);

  BLOCK_COMMENT("} resolve_cache_and_index_for_field");
}

// The cache register (the only input reg) must be set before call.
void TemplateTable::load_resolved_field_entry(Register obj,
                                              Register cache,
                                              Register tos_state,
                                              Register offset,
                                              Register flags,
                                              bool is_static = false) {
  assert_different_registers(cache, tos_state, flags, offset);

  // Field offset
  __ load_sized_value(offset, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(int), true /*is_signed*/);

  // Flags
  __ load_sized_value(flags, Address(cache, in_bytes(ResolvedFieldEntry::flags_offset())), sizeof(u1), false);

  // TOS state
  if (tos_state != noreg) {
    __ load_sized_value(tos_state, Address(cache, in_bytes(ResolvedFieldEntry::type_offset())), sizeof(u1), false);
  }

  // Klass overwrite register
  if (is_static) {
    __ load_sized_value(obj, Address(cache, ResolvedFieldEntry::field_holder_offset()), sizeof(void*), false);
    __ load_sized_value(obj, Address(obj, in_bytes(Klass::java_mirror_offset())), sizeof(void*), false);
    __ resolve_oop_handle(obj);
  }
}

void TemplateTable::load_invokedynamic_entry(Register method) {
  const Register cache    = Z_tmp_1;
  const Register index    = Z_tmp_3;
  const Register appendix = Z_R1_scratch;
  assert_different_registers(cache, index, appendix, method);

  Label resolved;
  __ load_resolved_indy_entry(cache, index);
  __ z_lg(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset())));

  // The invokedynamic is unresolved iff method is null
  __ compare64_and_branch(method, (unsigned long)nullptr, Assembler::bcondNotEqual, resolved); // method != 0, jump to resolved
  Bytecodes::Code code = bytecode();
  // Call to the interpreter runtime to resolve invokedynamic
  address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
  __ load_const_optimized(Z_ARG2, (int)code);
  __ call_VM(noreg, entry, Z_ARG2);
  // Update registers with resolved info
  __ load_resolved_indy_entry(cache, index);
  __ z_lg(method, Address(cache, in_bytes(ResolvedIndyEntry::method_offset())));
#ifdef ASSERT
  __ compare64_and_branch(method, (unsigned long)nullptr, Assembler::bcondNotEqual, resolved); // method != 0, jump to resolved
  __ stop("should be resolved by now");
#endif // ASSERT
  __ bind(resolved);

  Label L_no_push;
  __ load_sized_value(index, Address(cache, in_bytes(ResolvedIndyEntry::flags_offset())), sizeof(u1), false /*is_signed*/);
  __ testbit(index, ResolvedIndyEntry::has_appendix_shift);
  __ z_bfalse(L_no_push);
  // get appendix
  __ load_sized_value(index, Address(cache, in_bytes(ResolvedIndyEntry::resolved_references_index_offset())), sizeof(u2), false /*is_signed*/);
  // Push the appendix as a trailing parameter.
  // This must be done before we get the receiver,
  // since the parameter_size includes it.
  __ load_resolved_reference_at_index(appendix, index);
  __ verify_oop(appendix);
  __ push_ptr(appendix);  // Push appendix (MethodType, CallSite, etc.).
  __ bind(L_no_push);

  // Compute return type.
  Register ret_type = index;
  __ load_sized_value(ret_type, Address(cache, in_bytes(ResolvedIndyEntry::result_type_offset())), sizeof(u1), false /*is_signed*/);

  const address table_addr = (address)Interpreter::invoke_return_entry_table_for(code);
  __ load_absolute_address(Z_R14, table_addr);

  const int bit_shift = LogBytesPerWord;           // Size of each table entry.
  __ z_sllg(ret_type, ret_type, bit_shift);
  __ z_lg(Z_R14, Address(Z_R14, ret_type));
}

void TemplateTable::load_resolved_method_entry_handle(Register cache,
                                                      Register method,
                                                      Register ref_index,
                                                      Register flags) {
  assert_different_registers(method, cache, ref_index, flags);

  // determine constant pool cache field offsets
  resolve_cache_and_index_for_method(f1_byte, cache, method /* index */);

  // maybe push appendix to arguments (just before return address)
  Label L_no_push;
  __ load_sized_value(flags, Address(cache, in_bytes(ResolvedMethodEntry::flags_offset())), sizeof(u1), false /* is signed */);
  __ testbit(flags, ResolvedMethodEntry::has_appendix_shift); // life ended for flags
  __ z_bfalse(L_no_push);
  // invokehandle uses an index into the resolved references array
  __ load_sized_value(ref_index, Address(cache, in_bytes(ResolvedMethodEntry::resolved_references_index_offset())), sizeof(u2), false /* is signed */);
  // Push the appendix as a trailing parameter.
  // This must be done before we get the receiver,
  // since the parameter_size includes it.
  Register appendix = method;
  __ load_resolved_reference_at_index(appendix, ref_index);
  __ verify_oop(appendix);
  __ push_ptr(appendix);  // Push appendix (MethodType, CallSite, etc.).
  __ bind(L_no_push);

  __ z_lg(method, Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
}

// The registers cache and index are set up if needed.
// However, the field entry must have been resolved before.
// If no jvmti post operation is performed, their contents remains unchanged.
// After a jvmti post operation, the registers are re-calculated by load_field_entry().
void TemplateTable::jvmti_post_field_access(Register cache, Register index,
                                            bool is_static, bool has_tos) {

  // Do the JVMTI work here to avoid disturbing the register state below.
  // We use c_rarg registers here because we want to use the register used in
  // the call to the VM
  if (!JvmtiExport::can_post_field_access()) {
    return;
  }

  // Check to see if a field access watch has been set before we
  // take the time to call into the VM.
  Label dontPost;
  assert_different_registers(cache, index, Z_tos);
  __ load_absolute_address(Z_tos, (address)JvmtiExport::get_field_access_count_addr());
  __ z_chsi(0, Z_tos, 0); // avoid loading data into a scratch register
  __ z_bre(dontPost);

  // cache entry pointer
  // __ load_field_entry(cache, index); // not required as already set by resolve_cache_and_index_for_field()

  if (is_static) {
    __ clear_reg(Z_ARG2, true, false); // null object reference. Don't set CC.
  } else {
    __ load_ptr(0, Z_ARG2);  // Get object pointer without popping it.
    __ verify_oop(Z_ARG2);
  }

  // Z_ARG2: object pointer or null
  // cache:  cache entry pointer
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
             Z_ARG2, cache);

  // restore registers after runtime call.
  __ load_field_entry(cache, index);

  __ bind(dontPost);
}

void TemplateTable::pop_and_check_object(Register r) {
  __ pop_ptr(r);
  __ null_check(r);  // for field access must check obj.
  __ verify_oop(r);
}

void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
  transition(vtos, vtos);

  const Register obj           = Z_tmp_1;
  const Register off           = Z_tmp_2;
  const Register cache         = Z_tmp_1;
  const Register index         = Z_tmp_2;
  const Register flags         = Z_R1_scratch; // flags are not used in getfield
  const Register br_tab        = Z_R1_scratch;
  const Register tos_state     = Z_ARG4;
  const Register bc_reg        = Z_tmp_1;
  const Register patch_tmp     = Z_ARG4;
  const Register oopLoad_tmp1  = Z_R1_scratch;
  const Register oopLoad_tmp2  = Z_ARG5;
#ifdef ASSERT
  const Register br_tab_temp   = Z_R0_scratch;  // for branch table verification code only
#endif


  // Register usage and life range
  //
  //  cache, index          : short-lived. Their life ends after load_resolved_field_entry.
  //  obj (overwrites cache): long-lived. Used in branch table entries.
  //  off (overwrites index): long-lived. Used in branch table entries.
  //  flags                 : unused in getfield.
  //  br_tab                : short-lived. Only used to address branch table, and for verification in BTB_BEGIN macro.
  //  tos_state             : short-lived. Only used to index the branch table entry.
  //  bc_reg                : short-lived. Used as work register in patch_bytecode.
  //
  resolve_cache_and_index_for_field(byte_no, cache, index);
  jvmti_post_field_access(cache, index, is_static, false);
  load_resolved_field_entry(obj, cache, tos_state, off, flags, is_static);

  if (!is_static) {
    // Obj is on the stack.
    pop_and_check_object(obj);
  }

  // Displacement is 0. No need to care about limited displacement range.
  const Address field(obj, off);

  Label    is_Byte, is_Bool,  is_Int,    is_Short, is_Char,
           is_Long, is_Float, is_Object, is_Double;
  Label    is_badState,  is_badState9, is_badStateA, is_badStateB,
           is_badStateC, is_badStateD, is_badStateE, is_badStateF;
  Label    branchTable, atosHandler,  Done;
  bool     do_rewrite   = !is_static && (rc == may_rewrite);
  bool     dont_rewrite = (is_static || (rc == may_not_rewrite));

  assert(do_rewrite == !dont_rewrite, "Oops, code is not fit for that");
  assert((btos == 0) && (atos == 8), "change branch table! ByteCodes may have changed");

  // Calculate branch table size. Generated code size depends on ASSERT and on bytecode rewriting.
#ifdef ASSERT
  const unsigned int bsize = dont_rewrite ? BTB_MINSIZE*1 : BTB_MINSIZE*4;
#else
  // Calculate branch table size.
  const unsigned int bsize = dont_rewrite ? BTB_MINSIZE*1 : BTB_MINSIZE*4;
#endif

  // Calculate address of branch table entry and branch there.
  {
    const int bit_shift = exact_log2(bsize); // Size of each branch table entry.
    __ z_larl(br_tab, branchTable);
    __ z_sllg(tos_state, tos_state, bit_shift);
    assert(tos_state != Z_R0_scratch, "shouldn't be");
    __ z_agr(br_tab, tos_state);
    __ z_bcr(Assembler::bcondAlways, br_tab);
  }

  __ align_address(bsize);
  BIND(branchTable);

  // btos
  BTB_BEGIN(is_Byte, bsize, "getfield_or_static:is_Byte");
  __ z_lb(Z_tos, field);
  __ push(btos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_bgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Byte, bsize, "getfield_or_static:is_Byte");

  // ztos
  BTB_BEGIN(is_Bool, bsize, "getfield_or_static:is_Bool");
  __ z_lb(Z_tos, field);
  __ push(ztos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    // Use btos rewriting, no truncating to t/f bit is needed for getfield.
    patch_bytecode(Bytecodes::_fast_bgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Bool, bsize, "getfield_or_static:is_Bool");

  // ctos
  BTB_BEGIN(is_Char, bsize, "getfield_or_static:is_Char");
  // Load into 64 bits, works on all CPUs.
  __ z_llgh(Z_tos, field);
  __ push(ctos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_cgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Char, bsize, "getfield_or_static:is_Char");

  // stos
  BTB_BEGIN(is_Short, bsize, "getfield_or_static:is_Short");
  __ z_lh(Z_tos, field);
  __ push(stos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_sgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Short, bsize, "getfield_or_static:is_Short");

  // itos
  BTB_BEGIN(is_Int, bsize, "getfield_or_static:is_Int");
  __ mem2reg_opt(Z_tos, field, false);
  __ push(itos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_igetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Int, bsize, "getfield_or_static:is_Int");

  // ltos
  BTB_BEGIN(is_Long, bsize, "getfield_or_static:is_Long");
  __ mem2reg_opt(Z_tos, field);
  __ push(ltos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_lgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Long, bsize, "getfield_or_static:is_Long");

  // ftos
  BTB_BEGIN(is_Float, bsize, "getfield_or_static:is_Float");
  __ mem2freg_opt(Z_ftos, field, false);
  __ push(ftos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_fgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Float, bsize, "getfield_or_static:is_Float");

  // dtos
  BTB_BEGIN(is_Double, bsize, "getfield_or_static:is_Double");
  __ mem2freg_opt(Z_ftos, field);
  __ push(dtos);
  // Rewrite bytecode to be faster.
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_dgetfield, bc_reg, patch_tmp);
  }
  __ z_bru(Done);
  BTB_END(is_Double, bsize, "getfield_or_static:is_Double");

  // atos
  BTB_BEGIN(is_Object, bsize, "getfield_or_static:is_Object");
  __ z_bru(atosHandler);
  BTB_END(is_Object, bsize, "getfield_or_static:is_Object");

  // Bad state detection comes at no extra runtime cost.
  BTB_BEGIN(is_badState9, bsize, "getfield_or_static:is_badState9");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badState9, bsize, "getfield_or_static:is_badState9");
  BTB_BEGIN(is_badStateA, bsize, "getfield_or_static:is_badStateA");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateA, bsize, "getfield_or_static:is_badStateA");
  BTB_BEGIN(is_badStateB, bsize, "getfield_or_static:is_badStateB");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateB, bsize, "getfield_or_static:is_badStateB");
  BTB_BEGIN(is_badStateC, bsize, "getfield_or_static:is_badStateC");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateC, bsize, "getfield_or_static:is_badStateC");
  BTB_BEGIN(is_badStateD, bsize, "getfield_or_static:is_badStateD");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateD, bsize, "getfield_or_static:is_badStateD");
  BTB_BEGIN(is_badStateE, bsize, "getfield_or_static:is_badStateE");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateE, bsize, "getfield_or_static:is_badStateE");
  BTB_BEGIN(is_badStateF, bsize, "getfield_or_static:is_badStateF");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateF, bsize, "getfield_or_static:is_badStateF");

  __ align_address(64);
  BIND(is_badState);  // Do this outside branch table. Needs a lot of space.
  {
    unsigned int b_off = __ offset();
    if (is_static) {
      __ stop_static("Bad state in getstatic");
    } else {
      __ stop_static("Bad state in getfield");
    }
    unsigned int e_off = __ offset();
  }

  __ align_address(64);
  BIND(atosHandler);  // Oops are really complicated to handle.
                      // There is a lot of code generated.
                      // Therefore: generate the handler outside of branch table.
                      // There is no performance penalty. The additional branch
                      // to here is compensated for by the fallthru to "Done".
  {
    unsigned int b_off = __ offset();
    do_oop_load(_masm, field, Z_tos, oopLoad_tmp1, oopLoad_tmp2, IN_HEAP);
    __ verify_oop(Z_tos);
    __ push(atos);
    if (do_rewrite) {
      patch_bytecode(Bytecodes::_fast_agetfield, bc_reg, patch_tmp);
    }
    unsigned int e_off = __ offset();
  }

  BIND(Done);
}

void TemplateTable::getfield(int byte_no) {
  BLOCK_COMMENT("getfield  {");
  getfield_or_static(byte_no, false);
  BLOCK_COMMENT("} getfield");
}

void TemplateTable::nofast_getfield(int byte_no) {
  getfield_or_static(byte_no, false, may_not_rewrite);
}

void TemplateTable::getstatic(int byte_no) {
  BLOCK_COMMENT("getstatic {");
  getfield_or_static(byte_no, true);
  BLOCK_COMMENT("} getstatic");
}

// Register cache is expected to be set before the call.
// This function may destroy various registers.
// Only the contents of register cache is preserved/restored.
void TemplateTable::jvmti_post_field_mod(Register cache,
                                         Register index, bool is_static) {
  transition(vtos, vtos);

  if (!JvmtiExport::can_post_field_modification()) {
    return;
  }

  BLOCK_COMMENT("jvmti_post_field_mod {");

  // Check to see if a field modification watch has been set
  // before we take the time to call into the VM.
  Label    dontPost;
  assert_different_registers(cache, index, Z_tos, Z_ARG2, Z_ARG3, Z_ARG4);
  __ load_absolute_address(Z_tos, (address)JvmtiExport::get_field_modification_count_addr());
  __ z_chsi(0, Z_tos, 0); // avoid loading data into a scratch register
  __ z_bre(dontPost);

  Register obj        = Z_ARG2;
  Register fieldEntry = Z_ARG3;
  Register value      = Z_ARG4;

  // Take a copy of cache entry pointer
  __ z_lgr(fieldEntry, cache);

  if (is_static) {
    // Life is simple. Null the object pointer.
    __ clear_reg(obj, true, false); // Don't set CC.
  } else {
    // Life is harder. The stack holds the value on top, followed by
    // the object. We don't know the size of the value, though. It
    // could be one or two words depending on its type. As a result,
    // we must find the type to determine where the object is.
    __ load_sized_value(value, Address(fieldEntry, in_bytes(ResolvedFieldEntry::type_offset())), sizeof(u1), false);

    __ mem2reg_opt(obj, at_tos(1)); // Initially assume a one word jvalue.

    if (VM_Version::has_LoadStoreConditional()) {
      __ z_chi(value, ltos);
      __ z_locg(obj, at_tos(2), Assembler::bcondEqual);
      __ z_chi(value, dtos);
      __ z_locg(obj, at_tos(2), Assembler::bcondEqual);
    } else {
      NearLabel load_dtos, cont;

      __ z_chi(value, ltos);
      __ z_brne(load_dtos);
      __ mem2reg_opt(obj, at_tos(2)); // ltos (two word jvalue)
      __ z_bru(cont);

      __ bind(load_dtos);
      __ z_chi(value, dtos);
      __ z_brne(cont);
      __ mem2reg_opt(obj, at_tos(2)); // dtos (two word jvalue)

      __ bind(cont);
    }
  }

  // object(tos)
  __ load_address(value, Address(Z_esp, Interpreter::expr_offset_in_bytes(0)));
  // obj:        object pointer set up above (null if static)
  // fieldEntry: field entry pointer
  // value:      jvalue object on the stack
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification),
             obj, fieldEntry, value);

  // Reload field entry
  __ load_field_entry(cache, index);

  __ bind(dontPost);
  BLOCK_COMMENT("} jvmti_post_field_mod");
}


void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
  transition(vtos, vtos);

  const Register obj           = Z_ARG5;
  const Register off           = Z_tmp_2;
  const Register cache         = Z_ARG5;
  const Register index         = Z_tmp_2;
  const Register fieldAddr     = Z_tmp_2;      // contains obj and off combined. Could be any address register.
  const Register flags         = Z_tmp_1;      // preserves flag value till the end, for volatility check
  const Register br_tab        = Z_R1_scratch;
  const Register tos_state     = Z_ARG4;
  const Register bc_reg        = Z_tmp_2;
  const Register patch_tmp     = Z_ARG4;
  const Register oopStore_tmp1 = Z_R1_scratch;
  const Register oopStore_tmp2 = Z_ARG5;       // tmp2 must be non-volatile reg
  const Register oopStore_tmp3 = Z_R0_scratch;
#ifdef ASSERT
  const Register br_tab_temp   = Z_R0_scratch; // for branch table verification code only
#endif

/*
 *  Register usage and life range
 *
 *  cache, index          : short-lived. Their life ends after load_resolved_field_entry.
 *  obj (overwrites cache): very short-lived, Combined with off immediately.
 *  off (overwrites index): long-lived, Used in branch table entries.
 *  flags                 : long-lived, Has to survive until the end to determine volatility.
 *  br_tab                : short-lived, Only used to address branch table, and for verification in BTB_BEGIN macro.
 *  tos_state             : short-live, Only used to index the branch table entry.
 *  bc_reg                : short-lived, Used as work register in patch_bytecode.
*/
  resolve_cache_and_index_for_field(byte_no, cache, index);
  jvmti_post_field_mod(cache, index, is_static);
  load_resolved_field_entry(obj, cache, tos_state, off, flags, is_static);

  const Address field(fieldAddr);
  __ lgr_if_needed(fieldAddr, off);

  /*
   * In the static case, we can calculate the final field address easily.
   * Do so to occupy only one non-volatile register
   * ---------------------
   * In the non-static case, we preset fieldAddr with the field offset.
   * The object address is available only later. It is popped from stack.
   * see pop_and_check_object(obj);
   */
  if (is_static) {
    __ z_agr(fieldAddr, obj);
  }

  Label is_Byte, is_Bool,  is_Int,    is_Short, is_Char,
        is_Long, is_Float, is_Object, is_Double;
  Label is_badState,  is_badState9, is_badStateA, is_badStateB,
        is_badStateC, is_badStateD, is_badStateE, is_badStateF;
  Label branchTable, atosHandler, Done;
  bool  do_rewrite   = !is_static && (rc == may_rewrite);
  bool  dont_rewrite = (is_static || (rc == may_not_rewrite));

  assert(do_rewrite == !dont_rewrite, "Oops, code is not fit for that");
  assert((btos == 0) && (atos == 8), "change branch table! ByteCodes may have changed");

#ifdef ASSERT
  const unsigned int bsize = is_static ? BTB_MINSIZE*1 : BTB_MINSIZE*8;
#else
  const unsigned int bsize = is_static ? BTB_MINSIZE*1 : BTB_MINSIZE*8;
#endif

  // Calculate address of branch table entry and branch there.
  {
    const int bit_shift = exact_log2(bsize); // Size of each branch table entry.
    __ z_larl(br_tab, branchTable);
    __ z_sllg(tos_state, tos_state, bit_shift);
    assert(tos_state != Z_R0_scratch, "shouldn't be");
    __ z_agr(br_tab, tos_state);
    __ z_bcr(Assembler::bcondAlways, br_tab);
  }

  __ align_address(bsize);
  BIND(branchTable);

  // btos
  BTB_BEGIN(is_Byte, bsize, "putfield_or_static:is_Byte");
  __ pop(btos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ z_stc(Z_tos, field);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_bputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Byte, bsize, "putfield_or_static:is_Byte");

  // ztos
  BTB_BEGIN(is_Bool, bsize, "putfield_or_static:is_Bool");
  __ pop(ztos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ z_nilf(Z_tos, 0x1);
  __ z_stc(Z_tos, field);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_zputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Bool, bsize, "putfield_or_static:is_Bool");

  // ctos
  BTB_BEGIN(is_Char, bsize, "putfield_or_static:is_Char");
  __ pop(ctos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ z_sth(Z_tos, field);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_cputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Char, bsize, "putfield_or_static:is_Char");

  // stos
  BTB_BEGIN(is_Short, bsize, "putfield_or_static:is_Short");
  __ pop(stos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ z_sth(Z_tos, field);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_sputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Short, bsize, "putfield_or_static:is_Short");

  // itos
  BTB_BEGIN(is_Int, bsize, "putfield_or_static:is_Int");
  __ pop(itos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ reg2mem_opt(Z_tos, field, false);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_iputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Int, bsize, "putfield_or_static:is_Int");

  // ltos
  BTB_BEGIN(is_Long, bsize, "putfield_or_static:is_Long");
  __ pop(ltos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ reg2mem_opt(Z_tos, field);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_lputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Long, bsize, "putfield_or_static:is_Long");

  // ftos
  BTB_BEGIN(is_Float, bsize, "putfield_or_static:is_Float");
  __ pop(ftos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ freg2mem_opt(Z_ftos, field, false);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_fputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Float, bsize, "putfield_or_static:is_Float");

  // dtos
  BTB_BEGIN(is_Double, bsize, "putfield_or_static:is_Double");
  __ pop(dtos);
  if (!is_static) {
    pop_and_check_object(obj);
    __ z_agr(fieldAddr, obj);
  }
  __ freg2mem_opt(Z_ftos, field);
  if (do_rewrite) {
    patch_bytecode(Bytecodes::_fast_dputfield, bc_reg, patch_tmp, true, byte_no);
  }
  __ z_bru(Done);
  BTB_END(is_Double, bsize, "putfield_or_static:is_Double");

  // atos
  BTB_BEGIN(is_Object, bsize, "putfield_or_static:is_Object");
  __ z_bru(atosHandler);
  BTB_END(is_Object, bsize, "putfield_or_static:is_Object");

  // Bad state detection comes at no extra runtime cost.
  BTB_BEGIN(is_badState9, bsize, "putfield_or_static:is_badState9");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badState9, bsize, "putfield_or_static:is_badState9");
  BTB_BEGIN(is_badStateA, bsize, "putfield_or_static:is_badStateA");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateA, bsize, "putfield_or_static:is_badStateA");
  BTB_BEGIN(is_badStateB, bsize, "putfield_or_static:is_badStateB");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateB, bsize, "putfield_or_static:is_badStateB");
  BTB_BEGIN(is_badStateC, bsize, "putfield_or_static:is_badStateC");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateC, bsize, "putfield_or_static:is_badStateC");
  BTB_BEGIN(is_badStateD, bsize, "putfield_or_static:is_badStateD");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateD, bsize, "putfield_or_static:is_badStateD");
  BTB_BEGIN(is_badStateE, bsize, "putfield_or_static:is_badStateE");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateE, bsize, "putfield_or_static:is_badStateE");
  BTB_BEGIN(is_badStateF, bsize, "putfield_or_static:is_badStateF");
  __ z_illtrap();
  __ z_bru(is_badState);
  BTB_END(is_badStateF, bsize, "putfield_or_static:is_badStateF");

  __ align_address(64);
  BIND(is_badState);  // Do this outside branch table. Needs a lot of space.
  {
    unsigned int b_off = __ offset();
    if (is_static) __ stop_static("Bad state in putstatic");
    else           __ stop_static("Bad state in putfield");
    unsigned int e_off = __ offset();
  }

  __ align_address(64);
  BIND(atosHandler);  // Oops are really complicated to handle.
                      // There is a lot of code generated.
                      // Therefore: generate the handler outside of branch table.
                      // There is no performance penalty. The additional branch
                      // to here is compensated for by the fallthru to "Done".
  {
    unsigned int b_off = __ offset();
    __ pop(atos);
    if (!is_static) {
      pop_and_check_object(obj);
      __ z_agr(fieldAddr, obj);
    }
    // Store into the field
    do_oop_store(_masm, field, Z_tos,
                 oopStore_tmp1, oopStore_tmp2, oopStore_tmp3, IN_HEAP);
    if (do_rewrite) {
      patch_bytecode(Bytecodes::_fast_aputfield, bc_reg, patch_tmp, true, byte_no);
    }
    // __ z_bru(Done); // fallthru
    unsigned int e_off = __ offset();
  }

  BIND(Done);

  // Check for volatile store.
  // only if flags register is non-volatile
  NearLabel notVolatile;

  assert(flags.is_nonvolatile(), "flags register needs to be non-volatile");
  __ testbit(flags, ResolvedFieldEntry::is_volatile_shift);
  __ z_brz(notVolatile);

  __ z_fence();

  BIND(notVolatile);
}

void TemplateTable::putfield(int byte_no) {
  BLOCK_COMMENT("putfield  {");
  putfield_or_static(byte_no, false);
  BLOCK_COMMENT("} putfield");
}

void TemplateTable::nofast_putfield(int byte_no) {
  putfield_or_static(byte_no, false, may_not_rewrite);
}

void TemplateTable::putstatic(int byte_no) {
  BLOCK_COMMENT("putstatic {");
  putfield_or_static(byte_no, true);
  BLOCK_COMMENT("} putstatic");
}

// Push the tos value back to the stack.
// gc will find oops there and update.
void TemplateTable::jvmti_post_fast_field_mod() {

  if (!JvmtiExport::can_post_field_modification()) {
    return;
  }

  BLOCK_COMMENT("jvmti_post_fast_field_mod {");

  // Check to see if a field modification watch has been set
  // before we take the time to call into the VM.
  Label dontPost;
  __ load_absolute_address(Z_R1_scratch, (address)JvmtiExport::get_field_modification_count_addr());
  __ z_chsi(0, Z_R1_scratch, 0); // avoid loading data into a scratch register
  __ z_bre(dontPost);

  Register obj        = Z_ARG2;
  Register fieldEntry = Z_ARG3;
  Register value      = Z_ARG4;

  __ load_ptr(0, obj);              // Copy the object pointer from tos.
  __ verify_oop(obj);               // and verify it

  // Save tos values before call_VM() clobbers them. Since we have
  // to do it for every data type, we use the saved values as the
  // jvalue object.
  switch (bytecode()) {          // Load values into the jvalue object.
    case Bytecodes::_fast_aputfield:
      __ push_ptr(Z_tos);
      break;
    case Bytecodes::_fast_bputfield:
    case Bytecodes::_fast_zputfield:
    case Bytecodes::_fast_sputfield:
    case Bytecodes::_fast_cputfield:
    case Bytecodes::_fast_iputfield:
      __ push_i(Z_tos);
      break;
    case Bytecodes::_fast_dputfield:
      __ push_d();
      break;
    case Bytecodes::_fast_fputfield:
      __ push_f();
      break;
    case Bytecodes::_fast_lputfield:
      __ push_l(Z_tos);
      break;

    default:
      ShouldNotReachHere();
  }

  // jvalue on the stack
  __ load_address(value, Address(Z_esp, Interpreter::expr_offset_in_bytes(0)));
  // Access constant pool cache entry.
  __ load_field_entry(fieldEntry, Z_tos, 1);
  __ verify_oop(obj);

  // obj        : object pointer copied above
  // fieldEntry : cache entry pointer
  // value      : jvalue object on the stack
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification),
             obj, fieldEntry, value);

  switch (bytecode()) {             // Restore tos values.
    case Bytecodes::_fast_aputfield:
      __ pop_ptr(Z_tos);
      break;
    case Bytecodes::_fast_bputfield:
    case Bytecodes::_fast_zputfield:
    case Bytecodes::_fast_sputfield:
    case Bytecodes::_fast_cputfield:
    case Bytecodes::_fast_iputfield:
      __ pop_i(Z_tos);
      break;
    case Bytecodes::_fast_dputfield:
      __ pop_d(Z_ftos);
      break;
    case Bytecodes::_fast_fputfield:
      __ pop_f(Z_ftos);
      break;
    case Bytecodes::_fast_lputfield:
      __ pop_l(Z_tos);
      break;
    default:
      break;
  }

  __ bind(dontPost);
  BLOCK_COMMENT("} jvmti_post_fast_field_mod");
}

void TemplateTable::fast_storefield(TosState state) {
  transition(state, vtos);

  jvmti_post_fast_field_mod();

  // Access constant pool cache.
  Register obj       = Z_tmp_1;
  Register cache     = Z_tmp_1;
  Register index     = Z_tmp_2;
  Register off       = Z_tmp_2;
  Register flags     = Z_ARG5;

  // Index comes in bytes, don't shift afterwards!
  __ load_field_entry(cache, index);
  // this call is for nonstatic. obj remains unchanged.
  load_resolved_field_entry(obj, cache, noreg, off, flags, false);

  // Get object from stack.
  pop_and_check_object(obj);

  // field address
  const Address field(obj, off);

  // access field
  switch (bytecode()) {
    case Bytecodes::_fast_aputfield:
      do_oop_store(_masm, field, Z_tos,
                   Z_ARG2, Z_ARG3, Z_ARG4, IN_HEAP);
      break;
    case Bytecodes::_fast_lputfield:
      __ reg2mem_opt(Z_tos, field);
      break;
    case Bytecodes::_fast_iputfield:
      __ reg2mem_opt(Z_tos, field, false);
      break;
    case Bytecodes::_fast_zputfield:
      __ z_nilf(Z_tos, 0x1);
      // fall through to bputfield
    case Bytecodes::_fast_bputfield:
      __ z_stc(Z_tos, field);
      break;
    case Bytecodes::_fast_sputfield:
      // fall through
    case Bytecodes::_fast_cputfield:
      __ z_sth(Z_tos, field);
      break;
    case Bytecodes::_fast_fputfield:
      __ freg2mem_opt(Z_ftos, field, false);
      break;
    case Bytecodes::_fast_dputfield:
      __ freg2mem_opt(Z_ftos, field);
      break;
    default:
      ShouldNotReachHere();
  }

  //  Check for volatile store.
  Label notVolatile;

  __ testbit(flags, ResolvedFieldEntry::is_volatile_shift);
  __ z_brz(notVolatile);
  __ z_fence();

  __ bind(notVolatile);
}

void TemplateTable::fast_accessfield(TosState state) {
  transition(atos, state);

  Register obj = Z_tos;  // Object ptr is in TOS

  // Do the JVMTI work here. There is no specific jvmti_post_fast_access() emitter.
  if (JvmtiExport::can_post_field_access()) {
    // Check to see if a field modification watch has been set
    // before we take the time to call into the VM.
    BLOCK_COMMENT("jvmti_post_fast_field_access {");
    Label    dontPost;
    Register cache = Z_ARG3;
    Register index = Z_tmp_2;

    __ load_absolute_address(Z_R1_scratch, (address)JvmtiExport::get_field_access_count_addr());
    __ z_chsi(0, Z_R1_scratch, 0); // avoid loading data into a scratch register
    __ z_bre(dontPost);

    // Access constant pool cache entry.
    __ load_field_entry(cache, index);

    __ verify_oop(obj);
    __ push_ptr(obj);  // Save object pointer before call_VM() clobbers it.
    __ z_lgr(Z_ARG2, obj);

    // Z_ARG2: object pointer copied above
    // cache: cache entry pointer
    __ call_VM(noreg,
               CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
               Z_ARG2, cache);
    __ pop_ptr(obj); // Restore object pointer.

    __ bind(dontPost);
    BLOCK_COMMENT("} jvmti_post_fast_field_access");
  }

  // Access constant pool cache.
  Register cache = Z_tmp_1;
  Register index = Z_tmp_2;
  Register off   = Z_tmp_2;

  // Index comes in bytes, don't shift afterwards!
  __ load_field_entry(cache, index);
  // Replace index with field offset from cache entry.
  __ load_sized_value(off, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(jint), true);

  __ verify_oop(obj);
  __ null_check(obj);

  Address field(obj, off);

  // access field
  switch (bytecode()) {
    case Bytecodes::_fast_agetfield:
      do_oop_load(_masm, field, Z_tos, Z_tmp_1, Z_tmp_2, IN_HEAP);
      __ verify_oop(Z_tos);
      return;
    case Bytecodes::_fast_lgetfield:
      __ mem2reg_opt(Z_tos, field);
      return;
    case Bytecodes::_fast_igetfield:
      __ mem2reg_opt(Z_tos, field, false);
      return;
    case Bytecodes::_fast_bgetfield:
      __ z_lb(Z_tos, field);
      return;
    case Bytecodes::_fast_sgetfield:
      __ z_lh(Z_tos, field);
      return;
    case Bytecodes::_fast_cgetfield:
      __ z_llgh(Z_tos, field);   // Load into 64 bits, works on all CPUs.
      return;
    case Bytecodes::_fast_fgetfield:
      __ mem2freg_opt(Z_ftos, field, false);
      return;
    case Bytecodes::_fast_dgetfield:
      __ mem2freg_opt(Z_ftos, field);
      return;
    default:
      ShouldNotReachHere();
  }
}

void TemplateTable::fast_xaccess(TosState state) {
  transition(vtos, state);

  Register receiver = Z_tos;
  // Get receiver.
  __ mem2reg_opt(Z_tos, aaddress(0));

  // Access constant pool cache.
  Register cache = Z_tmp_1;
  Register index = Z_tmp_2;
  Register off   = Z_tmp_2;

  // Index comes in bytes, don't shift afterwards!
  __ load_field_entry(cache, index, 2);
  // Replace index with field offset from cache entry.
  __ load_sized_value(off, Address(cache, in_bytes(ResolvedFieldEntry::field_offset_offset())), sizeof(jint), true);

  // Make sure exception is reported in correct bcp range (getfield is
  // next instruction).
  __ add2reg(Z_bcp, 1);
  __ null_check(receiver);

  Address field(receiver, off);

  switch (state) {
    case itos:
      __ mem2reg_opt(Z_tos, field, false);
      break;
    case atos:
      do_oop_load(_masm, field, Z_tos, Z_tmp_1, Z_tmp_2, IN_HEAP);
      __ verify_oop(Z_tos);
      break;
    case ftos:
      __ mem2freg_opt(Z_ftos, field);
      break;
    default:
      ShouldNotReachHere();
  }

  // Reset bcp to original position.
  __ add2reg(Z_bcp, -1);
}

//-----------------------------------------------------------------------------
// Calls

void TemplateTable::prepare_invoke(Register cache, Register recv) {
  Bytecodes::Code code     = bytecode();
  const Register  ret_type = Z_R1_scratch;
  const bool load_receiver = (code != Bytecodes::_invokestatic) && (code != Bytecodes::_invokedynamic);
  assert_different_registers(ret_type, recv);

  // Load TOS state for later
  __ load_sized_value(ret_type, Address(cache, in_bytes(ResolvedMethodEntry::type_offset())), sizeof(u1), false /* is signed */);

  // load receiver if needed (note: no return address pushed yet)
  if (load_receiver) {
    __ load_sized_value(recv, Address(cache, in_bytes(ResolvedMethodEntry::num_parameters_offset())), sizeof(u2), false /* is signed */);
    const unsigned int bit_shift = Interpreter::logStackElementSize;
    __ z_sllg(recv, recv, bit_shift);
    // recv now contains #arguments * StackElementSize.

    Address recv_addr(Z_esp, recv);
    __ z_lg(recv, recv_addr);
    __ verify_oop(recv);
  }

  // Compute return type.
  // ret_type is used by callers (invokespecial, invokestatic) at least.
  const address table_addr = (address)Interpreter::invoke_return_entry_table_for(code);
  __ load_absolute_address(Z_R14, table_addr);
  __ z_sllg(ret_type, ret_type, LogBytesPerWord);

  __ z_lg(Z_R14, Address(Z_R14, ret_type)); // Load return address.
}

void TemplateTable::load_resolved_method_entry_interface(Register cache,
                                                         Register klass,
                                                         Register method_or_table_index,
                                                         Register flags) {
  assert_different_registers(method_or_table_index, cache, flags, klass);
  BLOCK_COMMENT("load_resolved_method_entry_interface {");
  // determine constant pool cache field offsets
  const Register index = flags; // not containing anything important, let's kill it.
  resolve_cache_and_index_for_method(f1_byte, cache, index);
  __ load_sized_value(flags, Address(cache, in_bytes(ResolvedMethodEntry::flags_offset())), sizeof(u1), false /* is signed*/);

  // Invokeinterface can behave in different ways:
  // If calling a method from java.lang.Object, the forced virtual flag is true so the invocation will
  // behave like an invokevirtual call. The state of the virtual final flag will determine whether a method or
  // vtable index is placed in the register.
  // Otherwise, the registers will be populated with the klass and method.
  Label NotVirtual, NotVFinal, Done;
  __ testbit(flags, ResolvedMethodEntry::is_forced_virtual_shift);
  __ z_brz(NotVirtual);
  __ testbit(flags, ResolvedMethodEntry::is_vfinal_shift);
  __ z_brz(NotVFinal);
  __ z_lg(method_or_table_index, Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
  __ z_bru(Done);

  __ bind(NotVFinal);
  __ load_sized_value(method_or_table_index, Address(cache, in_bytes(ResolvedMethodEntry::table_index_offset())), sizeof(u2), false /* is signed */);
  __ z_bru(Done);

  __ bind(NotVirtual);
  __ z_lg(method_or_table_index, Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
  __ z_lg(klass, Address(cache, in_bytes(ResolvedMethodEntry::klass_offset())));
  __ bind(Done);

  BLOCK_COMMENT("} load_resolved_method_entry_interface");
}

// Registers Killed: Z_R1
void TemplateTable::load_resolved_method_entry_virtual(Register cache,
                                                       Register method_or_table_index,
                                                       Register flags) {
  BLOCK_COMMENT("load_resolved_method_entry_virtual {");
  assert_different_registers(method_or_table_index, cache, flags);
  const Register index = flags; // doesn't contain valuable content, could be used as index for once

  // determine constant pool cache field offsets
  resolve_cache_and_index_for_method(f2_byte, cache, index);
  __ load_sized_value(flags, Address(cache, in_bytes(ResolvedMethodEntry::flags_offset())), sizeof(u1), false /*is_signed*/);

  // method_or_table_index can either be an itable index or a method depending on the virtual final flag
  Label NotVFinal, Done;
  __ testbit(flags, ResolvedMethodEntry::is_vfinal_shift);
  __ z_brz(NotVFinal);
  __ z_lg(method_or_table_index,  Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
  __ z_bru(Done);

  __ bind(NotVFinal);
  __ load_sized_value(method_or_table_index, Address(cache, in_bytes(ResolvedMethodEntry::table_index_offset())), sizeof(u2), false /* is signed */);
  __ bind(Done);
  BLOCK_COMMENT("} load_resolved_method_entry_virtual");
}

void TemplateTable::invokevirtual_helper(Register index,
                                         Register recv,
                                         Register flags) {
  // Uses temporary registers Z_tmp_2, Z_ARG4.
  assert_different_registers(index, recv, Z_tmp_2, Z_ARG4);

  // Test for an invoke of a final method.
  Label notFinal;

  BLOCK_COMMENT("invokevirtual_helper {");

  __ testbit(flags, ResolvedMethodEntry::is_vfinal_shift);
  __ z_brz(notFinal);

  const Register method = index;  // Method must be Z_ARG3.
  assert(method == Z_ARG3, "method must be second argument for interpreter calling convention");

  // Do the call - the index is actually the method to call.
  // That is, f2 is a vtable index if !is_vfinal, else f2 is a method.

  // It's final, need a null check here!
  __ null_check(recv);

  // Profile this call.
  __ profile_final_call(Z_tmp_2);
  __ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true); // Argument type profiling.
  __ jump_from_interpreted(method, Z_tmp_2);

  __ bind(notFinal);

  // Get receiver klass.
  __ load_klass(Z_tmp_2, recv);

  // Profile this call.
  __ profile_virtual_call(Z_tmp_2, Z_ARG4, Z_ARG5);

  // Get target method & entry point.
  __ z_sllg(index, index, exact_log2(vtableEntry::size_in_bytes()));
  __ mem2reg_opt(method,
                 Address(Z_tmp_2, index,
                         Klass::vtable_start_offset() + vtableEntry::method_offset()));
  __ profile_arguments_type(Z_ARG4, method, Z_ARG5, true);
  __ jump_from_interpreted(method, Z_ARG4);
  BLOCK_COMMENT("} invokevirtual_helper");
}

void TemplateTable::invokevirtual(int byte_no) {
  transition(vtos, vtos);

  assert(byte_no == f2_byte, "use this argument");
  const Register Rrecv   = Z_ARG1;
  const Register Rmethod = Z_ARG3;
  const Register Rflags  = Z_ARG2;

  load_resolved_method_entry_virtual(Rrecv,
                                     Rmethod,
                                     Rflags);
  prepare_invoke(Rrecv, Rrecv);

  // Z_ARG3 : index
  // Z_ARG1 : receiver
  // Z_ARG2 : flags
  invokevirtual_helper(Rmethod, Rrecv, Rflags);
}

void TemplateTable::invokespecial(int byte_no) {
  transition(vtos, vtos);

  assert(byte_no == f1_byte, "use this argument");
  Register Rmethod = Z_tmp_2;
  Register Rrecv   = Z_ARG3;
  load_resolved_method_entry_special_or_static(Rrecv,
                                               Rmethod,
                                               noreg); /* flags are not used here */
  prepare_invoke(Rrecv, Rrecv);
  __ verify_oop(Rrecv);
  __ null_check(Rrecv);
  // Do the call.
  __ profile_call(Z_ARG2);
  __ profile_arguments_type(Z_ARG2, Rmethod, Z_ARG5, false);
  __ jump_from_interpreted(Rmethod, Z_R1_scratch);
}

/*
 * There are only two callsite (invokestatic, invokespecial) for this method and both of them are passing
 * "noreg" for flags registers at present.
 */
void TemplateTable::load_resolved_method_entry_special_or_static(Register cache,
                                                                 Register method,
                                                                 Register flags) {
  assert_different_registers(method, cache, flags);

  // determine constant pool cache field offsets
  resolve_cache_and_index_for_method(f1_byte, cache, method /* index (temp) */);
  if (flags != noreg) {
    __ load_sized_value(flags, Address(cache, in_bytes(ResolvedMethodEntry::flags_offset())), sizeof(u1), false /* is signed */);
  }
  __ z_lg(method, Address(cache, in_bytes(ResolvedMethodEntry::method_offset())));
}

void TemplateTable::invokestatic(int byte_no) {
  transition(vtos, vtos);

  assert(byte_no == f1_byte, "use this argument");
  Register Rmethod = Z_tmp_2;
  Register Rrecv   = Z_ARG1;

  load_resolved_method_entry_special_or_static(Rrecv,
                                               Rmethod,
                                               noreg); /* flags are not used here */
  prepare_invoke(Rrecv, Rrecv);  // get receiver also for null check and flags
  // Do the call.
  __ profile_call(Z_ARG2);
  __ profile_arguments_type(Z_ARG2, Rmethod, Z_ARG5, false);
  __ jump_from_interpreted(Rmethod, Z_R1_scratch);
}

// Outdated feature, and we don't support it.
void TemplateTable::fast_invokevfinal(int byte_no) {
  transition(vtos, vtos);
  assert(byte_no == f2_byte, "use this argument");
  __ stop("fast_invokevfinal not used on linuxs390x");
}

void TemplateTable::invokeinterface(int byte_no) {
  transition(vtos, vtos);

  assert(byte_no == f1_byte, "use this argument");
  Register klass     = Z_ARG2,
           method    = Z_ARG3,
           interface = Z_ARG4,
           flags     = Z_ARG5,
           receiver  = Z_tmp_1;

  BLOCK_COMMENT("invokeinterface {");

  load_resolved_method_entry_interface(receiver,   // ResolvedMethodEntry*
                                       interface,  // Klass*  (interface klass (from f1))
                                       method,     // Method* or itable/vtable index
                                       flags);     // flags
  prepare_invoke(receiver, receiver);

  // Z_R14 (== Z_bytecode) : return entry

  // First check for Object case, then private interface method,
  // then regular interface method.

  // Special case of invokeinterface called for virtual method of
  // java.lang.Object. See cpCache.cpp for details.
  NearLabel notObjectMethod, no_such_method;
  __ testbit(flags, ResolvedMethodEntry::is_forced_virtual_shift);
  __ z_brz(notObjectMethod);
  invokevirtual_helper(method, receiver, flags);
  __ bind(notObjectMethod);

  // Check for private method invocation - indicated by vfinal
  NearLabel notVFinal;
  __ testbit(flags, ResolvedMethodEntry::is_vfinal_shift);
  __ z_brz(notVFinal);

  // Get receiver klass into klass - also a null check.
  __ load_klass(klass, receiver);

  NearLabel subtype, no_such_interface;

  __ check_klass_subtype(klass, interface, Z_tmp_2, flags/*scratch*/, subtype);
  // If we get here the typecheck failed
  __ z_bru(no_such_interface);
  __ bind(subtype);

  // do the call
  __ profile_final_call(Z_tmp_2);
  __ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true);
  __ jump_from_interpreted(method, Z_tmp_2);

  __ bind(notVFinal);

  // Get receiver klass into klass - also a null check.
  __ load_klass(klass, receiver);

  __ lookup_interface_method(klass, interface, noreg, noreg, /*temp*/Z_ARG1,
                             no_such_interface, /*return_method=*/false);

  // Profile this call.
  __ profile_virtual_call(klass, Z_ARG1/*mdp*/, flags/*scratch*/);

  // Find entry point to call.

  // Get declaring interface class from method
  __ load_method_holder(interface, method);

  // Get itable index from method
  Register index   = receiver,
           method2 = flags;
  __ z_lgf(index, Address(method, Method::itable_index_offset()));
  __ z_aghi(index, -Method::itable_index_max);
  __ z_lcgr(index, index);

  __ lookup_interface_method(klass, interface, index, method2, Z_tmp_2,
                             no_such_interface);

  // Check for abstract method error.
  // Note: This should be done more efficiently via a throw_abstract_method_error
  // interpreter entry point and a conditional jump to it in case of a null
  // method.
  __ compareU64_and_branch(method2, (intptr_t) 0,
                           Assembler::bcondZero, no_such_method);

  __ profile_arguments_type(Z_tmp_1, method2, Z_tmp_2, true);

  // Do the call.
  __ jump_from_interpreted(method2, Z_tmp_2);
  __ should_not_reach_here();

  // exception handling code follows...
  // Note: Must restore interpreter registers to canonical
  // state for exception handling to work correctly!

  __ bind(no_such_method);

  // Throw exception.
  // Pass arguments for generating a verbose error message.
  __ z_lgr(Z_tmp_1, method); // Prevent register clash.
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address,
                              InterpreterRuntime::throw_AbstractMethodErrorVerbose),
                              klass, Z_tmp_1);
  // The call_VM checks for exception, so we should never return here.
  __ should_not_reach_here();

  __ bind(no_such_interface);

  // Throw exception.
  // Pass arguments for generating a verbose error message.
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address,
                              InterpreterRuntime::throw_IncompatibleClassChangeErrorVerbose),
                              klass, interface);
  // The call_VM checks for exception, so we should never return here.
  __ should_not_reach_here();

  BLOCK_COMMENT("} invokeinterface");
  return;
}

void TemplateTable::invokehandle(int byte_no) {
  transition(vtos, vtos);

  const Register method = Z_tmp_2;
  const Register recv   = Z_ARG5;
  const Register mtype  = Z_tmp_1;
  const Register flags  = Z_R1_scratch;
  load_resolved_method_entry_handle(recv,
                                    method,
                                    mtype /* index */,
                                    flags );
  prepare_invoke(recv, recv);
  __ verify_method_ptr(method);
  __ verify_oop(recv);
  __ null_check(recv);

  // Note: Mtype is already pushed (if necessary) by prepare_invoke.

  // FIXME: profile the LambdaForm also.
  __ profile_final_call(Z_ARG2);
  __ profile_arguments_type(Z_ARG3, method, Z_ARG5, true);

  __ jump_from_interpreted(method, Z_ARG3);
}

void TemplateTable::invokedynamic(int byte_no) {
  transition(vtos, vtos);

  const Register Rmethod   = Z_tmp_2;

  load_invokedynamic_entry(Rmethod);

  // Rmethod: CallSite object
  // Rcallsite: MH.linkToCallSite method

  // Note: Callsite is already pushed

  // TODO: should make a type profile for any invokedynamic that takes a ref argument.
  // Profile this call.
  __ profile_call(Z_ARG2);
  __ profile_arguments_type(Z_ARG2, Rmethod, Z_ARG5, false);
  __ jump_from_interpreted(Rmethod, Z_ARG2);
}

//-----------------------------------------------------------------------------
// Allocation

// Original comment on "allow_shared_alloc":
// Always go the slow path.
//  + Eliminated optimization within the template-based interpreter:
//    If an allocation is done within the interpreter without using
//    tlabs, the interpreter tries to do the allocation directly
//    on the heap.
//  + That means the profiling hooks are not considered and allocations
//    get lost for the profiling framework.
//  + However, we do not think that this optimization is really needed,
//    so we always go now the slow path through the VM in this case --
//    spec jbb2005 shows no measurable performance degradation.
void TemplateTable::_new() {
  transition(vtos, atos);
  address prev_instr_address = nullptr;
  Register tags  = Z_tmp_1;
  Register RallocatedObject   = Z_tos;
  Register cpool = Z_ARG2;
  Register tmp = Z_ARG3; // RobjectFields==tmp and Rsize==offset must be a register pair.
  Register offset = Z_ARG4;
  Label slow_case;
  Label done;
  Label initialize_header;

  BLOCK_COMMENT("TemplateTable::_new {");
  __ get_2_byte_integer_at_bcp(offset/*dest*/, 1, InterpreterMacroAssembler::Unsigned);
  __ get_cpool_and_tags(cpool, tags);
  // Make sure the class we're about to instantiate has been resolved.
  // This is done before loading InstanceKlass to be consistent with the order
  // how Constant Pool is updated (see ConstantPool::klass_at_put).
  const int tags_offset = Array<u1>::base_offset_in_bytes();
  __ load_address(tmp, Address(tags, offset, tags_offset));
  __ z_cli(0, tmp, JVM_CONSTANT_Class);
  __ z_brne(slow_case);

  __ z_sllg(offset, offset, LogBytesPerWord); // Convert to offset.
  // Get InstanceKlass.
  Register iklass = cpool;
  __ load_resolved_klass_at_offset(cpool, offset, iklass);

  // make sure klass is initialized
  assert(VM_Version::supports_fast_class_init_checks(),
         "Optimization requires support for fast class initialization checks");
  __ clinit_barrier(iklass, Z_thread, nullptr /*L_fast_path*/, &slow_case);

  // Get instance_size in InstanceKlass (scaled to a count of bytes).
  Register Rsize = offset;
  __ z_llgf(Rsize, Address(iklass, Klass::layout_helper_offset()));
  __ z_tmll(Rsize, Klass::_lh_instance_slow_path_bit);
  __ z_btrue(slow_case);

  // Allocate the instance
  // 1) Try to allocate in the TLAB.
  // 2) If the above fails (or is not applicable), go to a slow case
  // (creates a new TLAB, etc.).
  // Note: compared to other architectures, s390's implementation always goes
  // to the slow path if TLAB is used and fails.
  if (UseTLAB) {
    Register RoldTopValue = RallocatedObject;
    Register RnewTopValue = tmp;
    __ z_lg(RoldTopValue, Address(Z_thread, JavaThread::tlab_top_offset()));
    __ load_address(RnewTopValue, Address(RoldTopValue, Rsize));
    __ z_cg(RnewTopValue, Address(Z_thread, JavaThread::tlab_end_offset()));
    __ z_brh(slow_case);
    __ z_stg(RnewTopValue, Address(Z_thread, JavaThread::tlab_top_offset()));

    Register RobjectFields = tmp;
    Register Rzero = Z_R1_scratch;
    __ clear_reg(Rzero, true /*whole reg*/, false); // Load 0L into Rzero. Don't set CC.

    if (!ZeroTLAB) {
      // The object is initialized before the header. If the object size is
      // zero, go directly to the header initialization.
      if (UseCompactObjectHeaders) {
        assert(is_aligned(oopDesc::base_offset_in_bytes(), BytesPerLong), "oop base offset must be 8-byte-aligned");
        __ z_aghi(Rsize, (int)-oopDesc::base_offset_in_bytes());
      } else {
        __ z_aghi(Rsize, (int)-sizeof(oopDesc)); // Subtract header size, set CC.
      }
      __ z_bre(initialize_header);             // Jump if size of fields is zero.

      // Initialize object fields.
      // See documentation for MVCLE instruction!!!
      assert(RobjectFields->encoding() % 2 == 0, "RobjectFields must be an even register");
      assert(Rsize->encoding() == (RobjectFields->encoding()+1),
             "RobjectFields and Rsize must be a register pair");
      assert(Rzero->encoding() % 2 == 1, "Rzero must be an odd register");

      // Set Rzero to 0 and use it as src length, then mvcle will copy nothing
      // and fill the object with the padding value 0.
      if (UseCompactObjectHeaders) {
        __ add2reg(RobjectFields, oopDesc::base_offset_in_bytes(), RallocatedObject);
      } else {
        __ add2reg(RobjectFields, sizeof(oopDesc), RallocatedObject);
      }
      __ move_long_ext(RobjectFields, as_Register(Rzero->encoding() - 1), 0);
    }

    // Initialize object header only.
    __ bind(initialize_header);
    if (UseCompactObjectHeaders) {
      __ z_lg(tmp, Address(iklass, in_bytes(Klass::prototype_header_offset())));
      __ z_stg(tmp, Address(RallocatedObject, oopDesc::mark_offset_in_bytes()));
    } else {
      __ store_const(Address(RallocatedObject, oopDesc::mark_offset_in_bytes()),
                     (long) markWord::prototype().value());
      __ store_klass_gap(Rzero, RallocatedObject);  // Zero klass gap for compressed oops.
      __ store_klass(iklass, RallocatedObject);     // Store klass last.
    }

    if (DTraceAllocProbes) {
      // Trigger dtrace event for fastpath.
      __ push(atos); // Save the return value.
      __ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(oopDesc*)>(SharedRuntime::dtrace_object_alloc)), RallocatedObject);
      __ pop(atos); // Restore the return value.
    }
    __ z_bru(done);
  }

  // slow case
  __ bind(slow_case);
  __ get_constant_pool(Z_ARG2);
  __ get_2_byte_integer_at_bcp(Z_ARG3/*dest*/, 1, InterpreterMacroAssembler::Unsigned);
  call_VM(Z_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), Z_ARG2, Z_ARG3);
  __ verify_oop(Z_tos);

  // continue
  __ bind(done);

  BLOCK_COMMENT("} TemplateTable::_new");
}

void TemplateTable::newarray() {
  transition(itos, atos);

  // Call runtime.
  __ z_llgc(Z_ARG2, at_bcp(1));   // type
  __ z_lgfr(Z_ARG3, Z_tos);       // size
  call_VM(Z_RET,
          CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray),
          Z_ARG2, Z_ARG3);
}

void TemplateTable::anewarray() {
  transition(itos, atos);
  __ get_2_byte_integer_at_bcp(Z_ARG3, 1, InterpreterMacroAssembler::Unsigned);
  __ get_constant_pool(Z_ARG2);
  __ z_lgfr(Z_ARG4, Z_tos);
  call_VM(Z_tos, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray),
          Z_ARG2, Z_ARG3, Z_ARG4);
}

void TemplateTable::arraylength() {
  transition(atos, itos);

  int offset = arrayOopDesc::length_offset_in_bytes();
  __ mem2reg_opt(Z_tos, Address(Z_tos, offset), false);
}

void TemplateTable::checkcast() {
  transition(atos, atos);

  NearLabel done, is_null, ok_is_subtype, quicked, resolved;

  BLOCK_COMMENT("checkcast {");
  // If object is null, we are almost done.
  __ compareU64_and_branch(Z_tos, (intptr_t) 0, Assembler::bcondZero, is_null);

  // Get cpool & tags index.
  Register cpool = Z_tmp_1;
  Register tags = Z_tmp_2;
  Register index = Z_ARG5;

  __ get_cpool_and_tags(cpool, tags);
  __ get_2_byte_integer_at_bcp(index, 1, InterpreterMacroAssembler::Unsigned);
  // See if bytecode has already been quicked.
  // Note: For CLI, we would have to add the index to the tags pointer first,
  // thus load and compare in a "classic" manner.
  __ z_llgc(Z_R0_scratch,
            Address(tags, index, Array<u1>::base_offset_in_bytes()));
  __ compareU64_and_branch(Z_R0_scratch, JVM_CONSTANT_Class,
                           Assembler::bcondEqual, quicked);

  __ push(atos); // Save receiver for result, and for GC.
  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
  __ get_vm_result_metadata(Z_tos);

  Register   receiver = Z_ARG4;
  Register   klass = Z_tos;
  Register   subklass = Z_ARG5;

  __ pop_ptr(receiver); // restore receiver
  __ z_bru(resolved);

  // Get superklass in klass and subklass in subklass.
  __ bind(quicked);

  __ z_lgr(Z_ARG4, Z_tos);  // Save receiver.
  __ z_sllg(index, index, LogBytesPerWord);  // index2bytes for addressing
  __ load_resolved_klass_at_offset(cpool, index, klass);

  __ bind(resolved);

  __ load_klass(subklass, receiver);

  // Generate subtype check. Object in receiver.
  // Superklass in klass. Subklass in subklass.
  __ gen_subtype_check(subklass, klass, Z_ARG3, Z_tmp_1, ok_is_subtype);

  // Come here on failure.
  __ push_ptr(receiver);
  // Object is at TOS, target klass oop expected in rax by convention.
  __ z_brul((address) Interpreter::_throw_ClassCastException_entry);

  // Come here on success.
  __ bind(ok_is_subtype);

  __ z_lgr(Z_tos, receiver); // Restore object.

  // Collect counts on whether this test sees nulls a lot or not.
  if (ProfileInterpreter) {
    __ z_bru(done);
    __ bind(is_null);
    __ profile_null_seen(Z_tmp_1);
  } else {
    __ bind(is_null);   // Same as 'done'.
  }

  __ bind(done);
  BLOCK_COMMENT("} checkcast");
}

void TemplateTable::instanceof() {
  transition(atos, itos);

  NearLabel done, is_null, ok_is_subtype, quicked, resolved;

  BLOCK_COMMENT("instanceof {");
  // If object is null, we are almost done.
  __ compareU64_and_branch(Z_tos, (intptr_t) 0, Assembler::bcondZero, is_null);

  // Get cpool & tags index.
  Register cpool = Z_tmp_1;
  Register tags = Z_tmp_2;
  Register index = Z_ARG5;

  __ get_cpool_and_tags(cpool, tags);
  __ get_2_byte_integer_at_bcp(index, 1, InterpreterMacroAssembler::Unsigned);
  // See if bytecode has already been quicked.
  // Note: For CLI, we would have to add the index to the tags pointer first,
  // thus load and compare in a "classic" manner.
  __ z_llgc(Z_R0_scratch,
            Address(tags, index, Array<u1>::base_offset_in_bytes()));
  __ compareU64_and_branch(Z_R0_scratch, JVM_CONSTANT_Class, Assembler::bcondEqual, quicked);

  __ push(atos); // Save receiver for result, and for GC.
  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
  __ get_vm_result_metadata(Z_tos);

  Register receiver = Z_tmp_2;
  Register klass = Z_tos;
  Register subklass = Z_tmp_2;

  __ pop_ptr(receiver); // Restore receiver.
  __ verify_oop(receiver);
  __ load_klass(subklass, subklass);
  __ z_bru(resolved);

  // Get superklass in klass and subklass in subklass.
  __ bind(quicked);

  __ load_klass(subklass, Z_tos);
  __ z_sllg(index, index, LogBytesPerWord);  // index2bytes for addressing
  __ load_resolved_klass_at_offset(cpool, index, klass);

  __ bind(resolved);

  // Generate subtype check.
  // Superklass in klass. Subklass in subklass.
  __ gen_subtype_check(subklass, klass, Z_ARG4, Z_ARG5, ok_is_subtype);

  // Come here on failure.
  __ clear_reg(Z_tos, true, false);
  __ z_bru(done);

  // Come here on success.
  __ bind(ok_is_subtype);
  __ load_const_optimized(Z_tos, 1);

  // Collect counts on whether this test sees nulls a lot or not.
  if (ProfileInterpreter) {
    __ z_bru(done);
    __ bind(is_null);
    __ profile_null_seen(Z_tmp_1);
  } else {
    __ bind(is_null);   // same as 'done'
  }

  __ bind(done);
  // tos = 0: obj is    null or  obj is not an instanceof the specified klass
  // tos = 1: obj isn't null and obj is     an instanceof the specified klass
  BLOCK_COMMENT("} instanceof");
}

//-----------------------------------------------------------------------------
// Breakpoints
void TemplateTable::_breakpoint() {

  // Note: We get here even if we are single stepping.
  // Jbug insists on setting breakpoints at every bytecode
  // even if we are in single step mode.

  transition(vtos, vtos);

  // Get the unpatched byte code.
  __ get_method(Z_ARG2);
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at),
             Z_ARG2, Z_bcp);
  // Save the result to a register that is preserved over C-function calls.
  __ z_lgr(Z_tmp_1, Z_RET);

  // Post the breakpoint event.
  __ get_method(Z_ARG2);
  __ call_VM(noreg,
             CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint),
             Z_ARG2, Z_bcp);

  // Must restore the bytecode, because call_VM destroys Z_bytecode.
  __ z_lgr(Z_bytecode, Z_tmp_1);

  // Complete the execution of original bytecode.
  __ dispatch_only_normal(vtos);
}


// Exceptions

void TemplateTable::athrow() {
  transition(atos, vtos);
  __ null_check(Z_tos);
  __ load_absolute_address(Z_ARG2, Interpreter::throw_exception_entry());
  __ z_br(Z_ARG2);
}

// Synchronization
//
// Note: monitorenter & exit are symmetric routines; which is reflected
//       in the assembly code structure as well
//
// Stack layout:
//
//               callers_sp        <- Z_SP (callers_sp == Z_fp (own fp))
//               return_pc
//               [rest of ABI_160]
//              /slot o:   free
//             / ...       free
//       oper. | slot n+1: free    <- Z_esp points to first free slot
//       stack | slot n:   val                      caches IJAVA_STATE.esp
//             | ...
//              \slot 0:   val
//              /slot m            <- IJAVA_STATE.monitors = monitor block top
//             | ...
//     monitors| slot 2
//             | slot 1
//              \slot 0
//              /slot l            <- monitor block bot
// ijava_state | ...
//             | slot 2
//              \slot 0
//                                 <- Z_fp
void TemplateTable::monitorenter() {
  transition(atos, vtos);

  BLOCK_COMMENT("monitorenter {");

  // Check for null object.
  __ null_check(Z_tos);
  const int entry_size = frame::interpreter_frame_monitor_size_in_bytes();
  NearLabel allocated;
  // Initialize entry pointer.
  const Register Rfree_slot = Z_tmp_1;
  __ clear_reg(Rfree_slot, true, false); // Points to free slot or null. Don't set CC.

  // Find a free slot in the monitor block from top to bot (result in Rfree_slot).
  {
    const Register Rcurr_monitor = Z_ARG2;
    const Register Rbot = Z_ARG3; // Points to word under bottom of monitor block.
    const Register Rlocked_obj = Z_ARG4;
    NearLabel loop, exit, not_free;
    // Starting with top-most entry.
    __ get_monitors(Rcurr_monitor); // Rcur_monitor = IJAVA_STATE.monitors
    __ add2reg(Rbot, -frame::z_ijava_state_size, Z_fp);

#ifdef ASSERT
    address reentry = nullptr;
    { NearLabel ok;
      __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondNotHigh, ok);
      reentry = __ stop_chain_static(reentry, "IJAVA_STATE.monitors points below monitor block bottom");
      __ bind(ok);
    }
    { NearLabel ok;
      __ compareU64_and_branch(Rcurr_monitor, Z_esp, Assembler::bcondHigh, ok);
      reentry = __ stop_chain_static(reentry, "IJAVA_STATE.monitors above Z_esp");
      __ bind(ok);
    }
#endif

    // Check if bottom reached, i.e. if there is at least one monitor.
    __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondEqual, exit);

    __ bind(loop);
    // Check if current entry is used.
    __ load_and_test_long(Rlocked_obj, Address(Rcurr_monitor, BasicObjectLock::obj_offset()));
    __ z_brne(not_free);
    // If not used then remember entry in Rfree_slot.
    __ z_lgr(Rfree_slot, Rcurr_monitor);
    __ bind(not_free);
    // Exit if current entry is for same object; this guarantees, that new monitor
    // used for recursive lock is above the older one.
    __ compareU64_and_branch(Rlocked_obj, Z_tos, Assembler::bcondEqual, exit);
    // otherwise advance to next entry
    __ add2reg(Rcurr_monitor, entry_size);
    // Check if bottom reached, if not at bottom then check this entry.
    __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondNotEqual, loop);
    __ bind(exit);
  }

  // Rfree_slot isn't null -> found one
  __ compareU64_and_branch(Rfree_slot, (intptr_t)0L, Assembler::bcondNotEqual, allocated);

  // Allocate one if there's no free slot.
  __ add_monitor_to_stack(false, Z_ARG3, Z_ARG4, Z_ARG5);
  __ get_monitors(Rfree_slot);

  // Rfree_slot: points to monitor entry.
  __ bind(allocated);

  // Increment bcp to point to the next bytecode, so exception
  // handling for async. exceptions work correctly.
  // The object has already been popped from the stack, so the
  // expression stack looks correct.
  __ add2reg(Z_bcp, 1, Z_bcp);

  // Store object.
  __ z_stg(Z_tos, in_bytes(BasicObjectLock::obj_offset()), Rfree_slot);
  __ lock_object(Rfree_slot, Z_tos);

  // Check to make sure this monitor doesn't cause stack overflow after locking.
  __ save_bcp();  // in case of exception
  __ generate_stack_overflow_check(0);

  // The bcp has already been incremented. Just need to dispatch to
  // next instruction.
  __ dispatch_next(vtos);

  BLOCK_COMMENT("} monitorenter");
}


void TemplateTable::monitorexit() {
  transition(atos, vtos);

  BLOCK_COMMENT("monitorexit {");

  // Check for null object.
  __ null_check(Z_tos);

  NearLabel found, not_found;
  const Register Rcurr_monitor = Z_ARG2;

  // Find matching slot.
  {
    const int entry_size = frame::interpreter_frame_monitor_size_in_bytes();
    NearLabel entry, loop;

    const Register Rbot = Z_ARG3; // Points to word under bottom of monitor block.
    const Register Rlocked_obj = Z_ARG4;
    // Starting with top-most entry.
    __ get_monitors(Rcurr_monitor); // Rcur_monitor = IJAVA_STATE.monitors
    __ add2reg(Rbot, -frame::z_ijava_state_size, Z_fp);

#ifdef ASSERT
    address reentry = nullptr;
    { NearLabel ok;
      __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondNotHigh, ok);
      reentry = __ stop_chain_static(reentry, "IJAVA_STATE.monitors points below monitor block bottom");
      __ bind(ok);
    }
    { NearLabel ok;
      __ compareU64_and_branch(Rcurr_monitor, Z_esp, Assembler::bcondHigh, ok);
      reentry = __ stop_chain_static(reentry, "IJAVA_STATE.monitors above Z_esp");
      __ bind(ok);
    }
#endif

    // Check if bottom reached, i.e. if there is at least one monitor.
    __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondEqual, not_found);

    __ bind(loop);
    // Check if current entry is for same object.
    __ z_lg(Rlocked_obj, Address(Rcurr_monitor, BasicObjectLock::obj_offset()));
    // If same object then stop searching.
    __ compareU64_and_branch(Rlocked_obj, Z_tos, Assembler::bcondEqual, found);
    // Otherwise advance to next entry.
    __ add2reg(Rcurr_monitor, entry_size);
    // Check if bottom reached, if not at bottom then check this entry.
    __ compareU64_and_branch(Rcurr_monitor, Rbot, Assembler::bcondNotEqual, loop);
  }

  __ bind(not_found);
  // Error handling. Unlocking was not block-structured.
  __ call_VM(noreg, CAST_FROM_FN_PTR(address,
                   InterpreterRuntime::throw_illegal_monitor_state_exception));
  __ should_not_reach_here();

  __ bind(found);
  __ push_ptr(Z_tos); // Make sure object is on stack (contract with oopMaps).
  __ unlock_object(Rcurr_monitor, Z_tos);
  __ pop_ptr(Z_tos); // Discard object.
  BLOCK_COMMENT("} monitorexit");
}

// Wide instructions
void TemplateTable::wide() {
  transition(vtos, vtos);

  __ z_llgc(Z_R1_scratch, at_bcp(1));
  __ z_sllg(Z_R1_scratch, Z_R1_scratch, LogBytesPerWord);
  __ load_absolute_address(Z_tmp_1, (address) Interpreter::_wentry_point);
  __ mem2reg_opt(Z_tmp_1, Address(Z_tmp_1, Z_R1_scratch));
  __ z_br(Z_tmp_1);
  // Note: the bcp increment step is part of the individual wide
  // bytecode implementations.
}

// Multi arrays
void TemplateTable::multianewarray() {
  transition(vtos, atos);

  __ z_llgc(Z_tmp_1, at_bcp(3)); // Get number of dimensions.
  // Slot count to byte offset.
  __ z_sllg(Z_tmp_1, Z_tmp_1, Interpreter::logStackElementSize);
  // Z_esp points past last_dim, so set to Z_ARG2 to first_dim address.
  __ load_address(Z_ARG2, Address(Z_esp, Z_tmp_1));
  call_VM(Z_RET,
          CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray),
          Z_ARG2);
  // Pop dimensions from expression stack.
  __ z_agr(Z_esp, Z_tmp_1);
}
