changeset 12252:2844bdfd7a99

8167673: [s390] The s390 port. Summary: template interpreter, C1, C2 Reviewed-by: kvn, simonis
author goetz
date Thu, 13 Oct 2016 14:49:34 +0200
parents a0cf41abef5d
children abb2824d2dfd 3609eb7f27fa
files src/cpu/s390/vm/abstractInterpreter_s390.cpp src/cpu/s390/vm/assembler_s390.cpp src/cpu/s390/vm/assembler_s390.hpp src/cpu/s390/vm/assembler_s390.inline.hpp src/cpu/s390/vm/bytes_s390.hpp src/cpu/s390/vm/c1_CodeStubs_s390.cpp src/cpu/s390/vm/c1_Defs_s390.hpp src/cpu/s390/vm/c1_FpuStackSim_s390.hpp src/cpu/s390/vm/c1_FrameMap_s390.cpp src/cpu/s390/vm/c1_FrameMap_s390.hpp src/cpu/s390/vm/c1_LIRAssembler_s390.cpp src/cpu/s390/vm/c1_LIRAssembler_s390.hpp src/cpu/s390/vm/c1_LIRGenerator_s390.cpp src/cpu/s390/vm/c1_LIR_s390.cpp src/cpu/s390/vm/c1_LinearScan_s390.cpp src/cpu/s390/vm/c1_LinearScan_s390.hpp src/cpu/s390/vm/c1_MacroAssembler_s390.cpp src/cpu/s390/vm/c1_MacroAssembler_s390.hpp src/cpu/s390/vm/c1_Runtime1_s390.cpp src/cpu/s390/vm/c1_globals_s390.hpp src/cpu/s390/vm/c2_globals_s390.hpp src/cpu/s390/vm/c2_init_s390.cpp src/cpu/s390/vm/codeBuffer_s390.hpp src/cpu/s390/vm/compiledIC_s390.cpp src/cpu/s390/vm/copy_s390.hpp src/cpu/s390/vm/debug_s390.cpp src/cpu/s390/vm/depChecker_s390.hpp src/cpu/s390/vm/disassembler_s390.hpp src/cpu/s390/vm/frame_s390.cpp src/cpu/s390/vm/frame_s390.hpp src/cpu/s390/vm/frame_s390.inline.hpp src/cpu/s390/vm/globalDefinitions_s390.hpp src/cpu/s390/vm/globals_s390.hpp src/cpu/s390/vm/icBuffer_s390.cpp src/cpu/s390/vm/icache_s390.cpp src/cpu/s390/vm/icache_s390.hpp src/cpu/s390/vm/interp_masm_s390.cpp src/cpu/s390/vm/interp_masm_s390.hpp src/cpu/s390/vm/interpreterRT_s390.cpp src/cpu/s390/vm/interpreterRT_s390.hpp src/cpu/s390/vm/javaFrameAnchor_s390.hpp src/cpu/s390/vm/jniFastGetField_s390.cpp src/cpu/s390/vm/jniTypes_s390.hpp src/cpu/s390/vm/jni_s390.h src/cpu/s390/vm/jvmciCodeInstaller_s390.cpp src/cpu/s390/vm/macroAssembler_s390.cpp src/cpu/s390/vm/macroAssembler_s390.hpp src/cpu/s390/vm/macroAssembler_s390.inline.hpp src/cpu/s390/vm/metaspaceShared_s390.cpp src/cpu/s390/vm/methodHandles_s390.cpp src/cpu/s390/vm/methodHandles_s390.hpp src/cpu/s390/vm/nativeInst_s390.cpp src/cpu/s390/vm/nativeInst_s390.hpp src/cpu/s390/vm/registerMap_s390.hpp src/cpu/s390/vm/registerSaver_s390.hpp src/cpu/s390/vm/register_definitions_s390.cpp src/cpu/s390/vm/register_s390.cpp src/cpu/s390/vm/register_s390.hpp src/cpu/s390/vm/relocInfo_s390.cpp src/cpu/s390/vm/relocInfo_s390.hpp src/cpu/s390/vm/runtime_s390.cpp src/cpu/s390/vm/s390.ad src/cpu/s390/vm/sharedRuntime_s390.cpp src/cpu/s390/vm/stubGenerator_s390.cpp src/cpu/s390/vm/stubRoutines_s390.cpp src/cpu/s390/vm/stubRoutines_s390.hpp src/cpu/s390/vm/templateInterpreterGenerator_s390.cpp src/cpu/s390/vm/templateTable_s390.cpp src/cpu/s390/vm/templateTable_s390.hpp src/cpu/s390/vm/vmStructs_s390.hpp src/cpu/s390/vm/vm_version_s390.cpp src/cpu/s390/vm/vm_version_s390.hpp src/cpu/s390/vm/vmreg_s390.cpp src/cpu/s390/vm/vmreg_s390.hpp src/cpu/s390/vm/vmreg_s390.inline.hpp src/cpu/s390/vm/vtableStubs_s390.cpp src/os_cpu/linux_s390/vm/atomic_linux_s390.hpp src/os_cpu/linux_s390/vm/bytes_linux_s390.inline.hpp src/os_cpu/linux_s390/vm/globals_linux_s390.hpp src/os_cpu/linux_s390/vm/orderAccess_linux_s390.inline.hpp src/os_cpu/linux_s390/vm/os_linux_s390.cpp src/os_cpu/linux_s390/vm/os_linux_s390.hpp src/os_cpu/linux_s390/vm/prefetch_linux_s390.inline.hpp src/os_cpu/linux_s390/vm/thread_linux_s390.cpp src/os_cpu/linux_s390/vm/thread_linux_s390.hpp src/os_cpu/linux_s390/vm/vmStructs_linux_s390.hpp
diffstat 86 files changed, 56900 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/abstractInterpreter_s390.cpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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 "precompiled.hpp"
+#include "interpreter/interpreter.hpp"
+#include "oops/constMethod.hpp"
+#include "oops/method.hpp"
+#include "runtime/frame.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/macros.hpp"
+
+int AbstractInterpreter::BasicType_as_index(BasicType type) {
+  int i = 0;
+  switch (type) {
+    case T_BOOLEAN: i = 0; break;
+    case T_CHAR   : i = 1; break;
+    case T_BYTE   : i = 2; break;
+    case T_SHORT  : i = 3; break;
+    case T_INT    : i = 4; break;
+    case T_LONG   : i = 5; break;
+    case T_VOID   : i = 6; break;
+    case T_FLOAT  : i = 7; break;
+    case T_DOUBLE : i = 8; break;
+    case T_OBJECT : i = 9; break;
+    case T_ARRAY  : i = 9; break;
+    default       : ShouldNotReachHere();
+  }
+  assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");
+  return i;
+}
+
+bool AbstractInterpreter::can_be_compiled(methodHandle m) {
+  // No special entry points that preclude compilation.
+  return true;
+}
+
+// How much stack a method top interpreter activation needs in words.
+int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
+
+  // We have to size the following 2 frames:
+  //
+  //   [TOP_IJAVA_FRAME_ABI]
+  //   [ENTRY_FRAME]
+  //
+  // This expands to (see frame_s390.hpp):
+  //
+  //   [TOP_IJAVA_FRAME_ABI]
+  //   [operand stack]                 > stack
+  //   [monitors]      (optional)      > monitors
+  //   [IJAVA_STATE]                   > interpreter_state
+  //   [PARENT_IJAVA_FRAME_ABI]
+  //   [callee's locals w/o arguments] \ locals
+  //   [outgoing arguments]            /
+  //   [ENTRY_FRAME_LOCALS]
+
+  int locals = method->max_locals() * BytesPerWord;
+  int interpreter_state = frame::z_ijava_state_size;
+
+  int stack = method->max_stack() * BytesPerWord;
+  int monitors = method->is_synchronized() ? frame::interpreter_frame_monitor_size_in_bytes() : 0;
+
+  int total_bytes =
+    frame::z_top_ijava_frame_abi_size +
+    stack +
+    monitors +
+    interpreter_state +
+    frame::z_parent_ijava_frame_abi_size +
+    locals +
+    frame::z_entry_frame_locals_size;
+
+  return (total_bytes/BytesPerWord);
+}
+
+// Returns number of stackElementWords needed for the interpreter frame with the
+// given sections.
+// This overestimates the stack by one slot in case of alignments.
+int AbstractInterpreter::size_activation(int max_stack,
+                                         int temps,
+                                         int extra_args,
+                                         int monitors,
+                                         int callee_params,
+                                         int callee_locals,
+                                         bool is_top_frame) {
+  // Note: This calculation must exactly parallel the frame setup
+  // in AbstractInterpreterGenerator::generate_method_entry.
+
+  assert((Interpreter::stackElementSize == frame::alignment_in_bytes), "must align frame size");
+  const int abi_scratch = is_top_frame ? (frame::z_top_ijava_frame_abi_size    / Interpreter::stackElementSize) :
+                                         (frame::z_parent_ijava_frame_abi_size / Interpreter::stackElementSize);
+
+  const int size =
+    max_stack                                                 +
+    (callee_locals - callee_params)                           + // Already counted in max_stack().
+    monitors * frame::interpreter_frame_monitor_size()        +
+    abi_scratch                                               +
+    frame::z_ijava_state_size / Interpreter::stackElementSize;
+
+  // Fixed size of an interpreter frame.
+  return size;
+}
+
+// Fills a sceletal interpreter frame generated during deoptimizations.
+//
+// Parameters:
+//
+// interpreter_frame != NULL:
+//   set up the method, locals, and monitors.
+//   The frame interpreter_frame, if not NULL, is guaranteed to be the
+//   right size, as determined by a previous call to this method.
+//   It is also guaranteed to be walkable even though it is in a skeletal state
+//
+// is_top_frame == true:
+//   We're processing the *oldest* interpreter frame!
+//
+// pop_frame_extra_args:
+//   If this is != 0 we are returning to a deoptimized frame by popping
+//   off the callee frame. We want to re-execute the call that called the
+//   callee interpreted, but since the return to the interpreter would pop
+//   the arguments off advance the esp by dummy popframe_extra_args slots.
+//   Popping off those will establish the stack layout as it was before the call.
+//
+
+void AbstractInterpreter::layout_activation(Method* method,
+                                            int tempcount,
+                                            int popframe_extra_args,
+                                            int moncount,
+                                            int caller_actual_parameters,
+                                            int callee_param_count,
+                                            int callee_locals_count,
+                                            frame* caller,
+                                            frame* interpreter_frame,
+                                            bool is_top_frame,
+                                            bool is_bottom_frame) {
+  // TOP_IJAVA_FRAME:
+  //
+  //    0 [TOP_IJAVA_FRAME_ABI]         -+
+  //   16 [operand stack]                | size
+  //      [monitors]      (optional)     |
+  //      [IJAVA_STATE]                 -+
+  //      Note: own locals are located in the caller frame.
+  //
+  // PARENT_IJAVA_FRAME:
+  //
+  //    0 [PARENT_IJAVA_FRAME_ABI]                    -+
+  //      [callee's locals w/o arguments]              |
+  //      [outgoing arguments]                         | size
+  //      [used part of operand stack w/o arguments]   |
+  //      [monitors]      (optional)                   |
+  //      [IJAVA_STATE]                               -+
+  //
+
+  // Now we know our caller, calc the exact frame layout and size
+  // z_ijava_state->locals - i*BytesPerWord points to i-th Java local (i starts at 0).
+  intptr_t* locals_base = (caller->is_interpreted_frame())
+    ? (caller->interpreter_frame_tos_address() + caller_actual_parameters - 1)
+    : (caller->sp()                            + method->max_locals()     - 1 +
+       frame::z_parent_ijava_frame_abi_size / Interpreter::stackElementSize);
+
+  intptr_t* monitor_base = (intptr_t*)((address)interpreter_frame->fp() - frame::z_ijava_state_size);
+  intptr_t* monitor      = monitor_base - (moncount * frame::interpreter_frame_monitor_size());
+  intptr_t* operand_stack_base = monitor;
+  intptr_t* tos          = operand_stack_base - tempcount - popframe_extra_args;
+  intptr_t* top_frame_sp =
+    operand_stack_base - method->max_stack() - frame::z_top_ijava_frame_abi_size / Interpreter::stackElementSize;
+  intptr_t* sender_sp;
+  if (caller->is_interpreted_frame()) {
+    sender_sp = caller->interpreter_frame_top_frame_sp();
+  } else if (caller->is_compiled_frame()) {
+    sender_sp = caller->fp() - caller->cb()->frame_size();
+    // The bottom frame's sender_sp is its caller's unextended_sp.
+    // It was already set when its skeleton was pushed (see push_skeleton_frames()).
+    // Note: the unextended_sp is required by nmethod::orig_pc_addr().
+    assert(is_bottom_frame && (sender_sp == caller->unextended_sp()),
+           "must initialize sender_sp of bottom skeleton frame when pushing it");
+  } else {
+    assert(caller->is_entry_frame(), "is there a new frame type??");
+    sender_sp = caller->sp(); // Call_stub only uses it's fp.
+  }
+
+  interpreter_frame->interpreter_frame_set_method(method);
+  interpreter_frame->interpreter_frame_set_mirror(method->method_holder()->java_mirror());
+  interpreter_frame->interpreter_frame_set_locals(locals_base);
+  interpreter_frame->interpreter_frame_set_monitor_end((BasicObjectLock *)monitor);
+  *interpreter_frame->interpreter_frame_cache_addr() = method->constants()->cache();
+  interpreter_frame->interpreter_frame_set_tos_address(tos);
+  interpreter_frame->interpreter_frame_set_sender_sp(sender_sp);
+  interpreter_frame->interpreter_frame_set_top_frame_sp(top_frame_sp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/assembler_s390.cpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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 "precompiled.hpp"
+#include "asm/assembler.inline.hpp"
+#include "compiler/disassembler.hpp"
+#include "gc/shared/collectedHeap.inline.hpp"
+#include "interpreter/interpreter.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
+#include "memory/resourceArea.hpp"
+#include "prims/methodHandles.hpp"
+#include "runtime/biasedLocking.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/objectMonitor.hpp"
+#include "runtime/os.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1CollectedHeap.inline.hpp"
+#include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#include "gc/g1/heapRegion.hpp"
+#endif
+
+// Convention: Use Z_R0 and Z_R1 instead of Z_scratch_* in all
+// assembler_s390.* files.
+
+// Convert the raw encoding form into the form expected by the
+// constructor for Address. This is called by adlc generated code.
+Address Address::make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) {
+  assert(scale == 0, "Scale should not be used on z/Architecture. The call to make_raw is "
+         "generated by adlc and this must mirror all features of Operands from machnode.hpp.");
+  assert(disp_reloc == relocInfo::none, "not implemented on z/Architecture.");
+
+  Address madr(as_Register(base), as_Register(index), in_ByteSize(disp));
+  return madr;
+}
+
+int AbstractAssembler::code_fill_byte() {
+  return 0x00; // Illegal instruction 0x00000000.
+}
+
+// Condition code masks. Details see enum branch_condition.
+// Although this method is meant for INT CCs, the Overflow/Ordered
+// bit in the masks has to be considered. The CC might have been set
+// by a float operation, but is evaluated while calculating an integer
+// result. See elementary test TestFloat.isNotEqual(FF)Z for example.
+Assembler::branch_condition Assembler::inverse_condition(Assembler::branch_condition cc) {
+  Assembler::branch_condition unordered_bit = (Assembler::branch_condition)(cc & bcondNotOrdered);
+  Assembler::branch_condition inverse_cc;
+
+  // Some are commented out to avoid duplicate labels.
+  switch (cc) {
+    case bcondNever       : inverse_cc = bcondAlways;      break;  //  0 -> 15
+    case bcondAlways      : inverse_cc = bcondNever;       break;  // 15 ->  0
+
+    case bcondOverflow    : inverse_cc = bcondNotOverflow; break;  //  1 -> 14
+    case bcondNotOverflow : inverse_cc = bcondOverflow;    break;  // 14 ->  1
+
+    default :
+      switch ((Assembler::branch_condition)(cc & bcondOrdered)) {
+        case bcondEqual       : inverse_cc = bcondNotEqual;  break;  //  8 ->  6
+        // case bcondZero        :
+        // case bcondAllZero     :
+
+        case bcondNotEqual    : inverse_cc = bcondEqual;     break;  //  6 ->  8
+        // case bcondNotZero     :
+        // case bcondMixed       :
+
+        case bcondLow         : inverse_cc = bcondNotLow;    break;  //  4 -> 10
+        // case bcondNegative    :
+
+        case bcondNotLow      : inverse_cc = bcondLow;       break;  // 10 ->  4
+        // case bcondNotNegative :
+
+        case bcondHigh        : inverse_cc = bcondNotHigh;   break;  //  2 -> 12
+        // case bcondPositive    :
+
+        case bcondNotHigh     : inverse_cc = bcondHigh;      break;  // 12 ->  2
+        // case bcondNotPositive :
+
+        default :
+          fprintf(stderr, "inverse_condition(%d)\n", (int)cc);
+          fflush(stderr);
+          ShouldNotReachHere();
+          return bcondNever;
+      }
+      // If cc is even, inverse_cc must be odd.
+      if (!unordered_bit) {
+        inverse_cc = (Assembler::branch_condition)(inverse_cc | bcondNotOrdered);
+      }
+      break;
+  }
+  return inverse_cc;
+}
+
+Assembler::branch_condition Assembler::inverse_float_condition(Assembler::branch_condition cc) {
+  Assembler::branch_condition  inverse_cc;
+
+  switch (cc) {
+    case bcondNever       : inverse_cc = bcondAlways;      break;  //  0
+    case bcondAlways      : inverse_cc = bcondNever;       break;  // 15
+
+    case bcondNotOrdered  : inverse_cc = bcondOrdered;     break;  // 14
+    case bcondOrdered     : inverse_cc = bcondNotOrdered;  break;  //  1
+
+    case bcondEqual                      : inverse_cc = (branch_condition)(bcondNotEqual + bcondNotOrdered);  break; //  8
+    case bcondNotEqual + bcondNotOrdered : inverse_cc = bcondEqual;  break;                                          //  7
+
+    case bcondLow      + bcondNotOrdered : inverse_cc = (branch_condition)(bcondHigh + bcondEqual);      break;      //  5
+    case bcondNotLow                     : inverse_cc = (branch_condition)(bcondLow  + bcondNotOrdered); break;      // 10
+
+    case bcondHigh                       : inverse_cc = (branch_condition)(bcondLow  + bcondNotOrdered + bcondEqual); break;  //  2
+    case bcondNotHigh  + bcondNotOrdered : inverse_cc = bcondHigh; break;                                                     // 13
+
+    default :
+      fprintf(stderr, "inverse_float_condition(%d)\n", (int)cc);
+      fflush(stderr);
+      ShouldNotReachHere();
+      return bcondNever;
+  }
+  return inverse_cc;
+}
+
+#ifdef ASSERT
+void Assembler::print_dbg_msg(outputStream* out, unsigned long inst, const char* msg, int ilen) {
+  out->flush();
+  switch (ilen) {
+    case 2:  out->print_cr("inst = %4.4x, %s",    (unsigned short)inst, msg); break;
+    case 4:  out->print_cr("inst = %8.8x, %s\n",    (unsigned int)inst, msg); break;
+    case 6:  out->print_cr("inst = %12.12lx, %s\n",               inst, msg); break;
+    default: out->print_cr("inst = %16.16lx, %s\n",               inst, msg); break;
+  }
+  out->flush();
+}
+
+void Assembler::dump_code_range(outputStream* out, address pc, const unsigned int range, const char* msg) {
+  out->cr();
+  out->print_cr("-------------------------------");
+  out->print_cr("--  %s", msg);
+  out->print_cr("-------------------------------");
+  out->print_cr("Hex dump    of +/-%d bytes around %p, interval [%p,%p)", range, pc, pc-range, pc+range);
+  os::print_hex_dump(out, pc-range, pc+range, 2);
+
+  out->cr();
+  out->print_cr("Disassembly of +/-%d bytes around %p, interval [%p,%p)", range, pc, pc-range, pc+range);
+  Disassembler::decode(pc, pc + range, out);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/assembler_s390.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,2530 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_ASSEMBLER_S390_HPP
+#define CPU_S390_VM_ASSEMBLER_S390_HPP
+
+#undef  LUCY_DBG
+
+#define NearLabel Label
+
+// Immediate is an abstraction to represent the various immediate
+// operands which exist on z/Architecture. Neither this class nor
+// instances hereof have an own state. It consists of methods only.
+class Immediate VALUE_OBJ_CLASS_SPEC {
+
+ public:
+    static bool is_simm(int64_t x, unsigned int nbits) {
+      // nbits < 2   --> false
+      // nbits >= 64 --> true
+      assert(2 <= nbits && nbits < 64, "Don't call, use statically known result.");
+      const int64_t min      = -(1L << (nbits-1));
+      const int64_t maxplus1 =  (1L << (nbits-1));
+      return min <= x && x < maxplus1;
+    }
+    static bool is_simm32(int64_t x) {
+      return is_simm(x, 32);
+    }
+    static bool is_simm20(int64_t x) {
+      return is_simm(x, 20);
+    }
+    static bool is_simm16(int64_t x) {
+      return is_simm(x, 16);
+    }
+    static bool is_simm8(int64_t x) {
+      return is_simm(x,  8);
+    }
+
+    // Test if x is within signed immediate range for nbits.
+    static bool is_uimm(int64_t x, unsigned int nbits) {
+      // nbits == 0  --> false
+      // nbits >= 64 --> true
+      assert(1 <= nbits && nbits < 64, "don't call, use statically known result");
+      const uint64_t xu       = (unsigned long)x;
+      const uint64_t maxplus1 = 1UL << nbits;
+      return xu < maxplus1; // Unsigned comparison. Negative inputs appear to be very large.
+    }
+    static bool is_uimm32(int64_t x) {
+      return is_uimm(x, 32);
+    }
+    static bool is_uimm16(int64_t x) {
+      return is_uimm(x, 16);
+    }
+    static bool is_uimm12(int64_t x) {
+      return is_uimm(x, 12);
+    }
+    static bool is_uimm8(int64_t x) {
+      return is_uimm(x,  8);
+    }
+};
+
+// Displacement is an abstraction to represent the various
+// displacements which exist with addresses on z/ArchiTecture.
+// Neither this class nor instances hereof have an own state. It
+// consists of methods only.
+class Displacement VALUE_OBJ_CLASS_SPEC {
+
+ public: // These tests are used outside the (Macro)Assembler world, e.g. in ad-file.
+
+  static bool is_longDisp(int64_t x) {  // Fits in a 20-bit displacement field.
+    return Immediate::is_simm20(x);
+  }
+  static bool is_shortDisp(int64_t x) { // Fits in a 12-bit displacement field.
+    return Immediate::is_uimm12(x);
+  }
+  static bool is_validDisp(int64_t x) { // Is a valid displacement, regardless of length constraints.
+    return is_longDisp(x);
+  }
+};
+
+// RelAddr is an abstraction to represent relative addresses in the
+// form they are used on z/Architecture for instructions which access
+// their operand with pc-relative addresses. Neither this class nor
+// instances hereof have an own state. It consists of methods only.
+class RelAddr VALUE_OBJ_CLASS_SPEC {
+
+ private: // No public use at all. Solely for (Macro)Assembler.
+
+  static bool is_in_range_of_RelAddr(address target, address pc, bool shortForm) {
+    // Guard against illegal branch targets, e.g. -1. Occurrences in
+    // CompiledStaticCall and ad-file. Do not assert (it's a test
+    // function!). Just return false in case of illegal operands.
+    if ((((uint64_t)target) & 0x0001L) != 0) return false;
+    if ((((uint64_t)pc)     & 0x0001L) != 0) return false;
+
+    if (shortForm) {
+      return Immediate::is_simm((int64_t)(target-pc), 17); // Relative short addresses can reach +/- 2**16 bytes.
+    } else {
+      return Immediate::is_simm((int64_t)(target-pc), 33); // Relative long addresses can reach +/- 2**32 bytes.
+    }
+  }
+
+  static bool is_in_range_of_RelAddr16(address target, address pc) {
+    return is_in_range_of_RelAddr(target, pc, true);
+  }
+  static bool is_in_range_of_RelAddr16(ptrdiff_t distance) {
+    return is_in_range_of_RelAddr((address)distance, 0, true);
+  }
+
+  static bool is_in_range_of_RelAddr32(address target, address pc) {
+    return is_in_range_of_RelAddr(target, pc, false);
+  }
+  static bool is_in_range_of_RelAddr32(ptrdiff_t distance) {
+    return is_in_range_of_RelAddr((address)distance, 0, false);
+  }
+
+  static int pcrel_off(address target, address pc, bool shortForm) {
+    assert(((uint64_t)target & 0x0001L) == 0, "target of a relative address must be aligned");
+    assert(((uint64_t)pc     & 0x0001L) == 0, "origin of a relative address must be aligned");
+
+    if ((target == NULL) || (target == pc)) {
+      return 0;  // Yet unknown branch destination.
+    } else {
+      guarantee(is_in_range_of_RelAddr(target, pc, shortForm), "target not within reach");
+      return (int)((target - pc)>>1);
+    }
+  }
+
+  static int pcrel_off16(address target, address pc) {
+    return pcrel_off(target, pc, true);
+  }
+  static int pcrel_off16(ptrdiff_t distance) {
+    return pcrel_off((address)distance, 0, true);
+  }
+
+  static int pcrel_off32(address target, address pc) {
+    return pcrel_off(target, pc, false);
+  }
+  static int pcrel_off32(ptrdiff_t distance) {
+    return pcrel_off((address)distance, 0, false);
+  }
+
+  static ptrdiff_t inv_pcrel_off16(int offset) {
+    return ((ptrdiff_t)offset)<<1;
+  }
+
+  static ptrdiff_t inv_pcrel_off32(int offset) {
+    return ((ptrdiff_t)offset)<<1;
+  }
+
+  friend class Assembler;
+  friend class MacroAssembler;
+  friend class NativeGeneralJump;
+};
+
+// Address is an abstraction used to represent a memory location
+// as passed to Z assembler instructions.
+//
+// Note: A register location is represented via a Register, not
+// via an address for efficiency & simplicity reasons.
+class Address VALUE_OBJ_CLASS_SPEC {
+ private:
+  Register _base;    // Base register.
+  Register _index;   // Index register
+  intptr_t _disp;    // Constant displacement.
+
+ public:
+  Address() :
+    _base(noreg),
+    _index(noreg),
+    _disp(0) {}
+
+  Address(Register base, Register index, intptr_t disp = 0) :
+    _base(base),
+    _index(index),
+    _disp(disp) {}
+
+  Address(Register base, intptr_t disp = 0) :
+    _base(base),
+    _index(noreg),
+    _disp(disp) {}
+
+  Address(Register base, RegisterOrConstant roc, intptr_t disp = 0) :
+    _base(base),
+    _index(noreg),
+    _disp(disp) {
+    if (roc.is_constant()) _disp += roc.as_constant(); else _index = roc.as_register();
+  }
+
+#ifdef ASSERT
+  // ByteSize is only a class when ASSERT is defined, otherwise it's an int.
+  Address(Register base, ByteSize disp) :
+    _base(base),
+    _index(noreg),
+    _disp(in_bytes(disp)) {}
+
+  Address(Register base, Register index, ByteSize disp) :
+    _base(base),
+    _index(index),
+    _disp(in_bytes(disp)) {}
+#endif
+
+  // Aborts if disp is a register and base and index are set already.
+  Address plus_disp(RegisterOrConstant disp) const {
+    Address a = (*this);
+    a._disp += disp.constant_or_zero();
+    if (disp.is_register()) {
+      if (a._index == noreg) {
+        a._index = disp.as_register();
+      } else {
+        guarantee(_base == noreg, "can not encode"); a._base = disp.as_register();
+      }
+    }
+    return a;
+  }
+
+  // A call to this is generated by adlc for replacement variable $xxx$$Address.
+  static Address make_raw(int base, int index, int scale, int disp, relocInfo::relocType disp_reloc);
+
+  bool is_same_address(Address a) const {
+    return _base == a._base && _index == a._index && _disp == a._disp;
+  }
+
+  // testers
+  bool has_base()  const { return _base  != noreg; }
+  bool has_index() const { return _index != noreg; }
+  bool has_disp()  const { return true; } // There is no "invalid" value.
+
+  bool is_disp12() const { return Immediate::is_uimm12(disp()); }
+  bool is_disp20() const { return Immediate::is_simm20(disp()); }
+  bool is_RSform()  { return has_base() && !has_index() && is_disp12(); }
+  bool is_RSYform() { return has_base() && !has_index() && is_disp20(); }
+  bool is_RXform()  { return has_base() &&  has_index() && is_disp12(); }
+  bool is_RXEform() { return has_base() &&  has_index() && is_disp12(); }
+  bool is_RXYform() { return has_base() &&  has_index() && is_disp20(); }
+
+  bool uses(Register r) { return _base == r || _index == r; };
+
+  // accessors
+  Register base()      const { return _base; }
+  Register baseOrR0()  const { assert(_base  != Z_R0, ""); return _base  == noreg ? Z_R0 : _base; }
+  Register index()     const { return _index; }
+  Register indexOrR0() const { assert(_index != Z_R0, ""); return _index == noreg ? Z_R0 : _index; }
+  intptr_t disp() const { return _disp; }
+  // Specific version for short displacement instructions.
+  int      disp12() const {
+    assert(is_disp12(), "displacement out of range for uimm12");
+    return _disp;
+  }
+  // Specific version for long displacement instructions.
+  int      disp20() const {
+    assert(is_disp20(), "displacement out of range for simm20");
+    return _disp;
+  }
+  intptr_t value() const { return _disp; }
+
+  friend class Assembler;
+};
+
+class AddressLiteral VALUE_OBJ_CLASS_SPEC {
+ private:
+  address          _address;
+  RelocationHolder _rspec;
+
+  RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) {
+    switch (rtype) {
+    case relocInfo::external_word_type:
+      return external_word_Relocation::spec(addr);
+    case relocInfo::internal_word_type:
+      return internal_word_Relocation::spec(addr);
+    case relocInfo::opt_virtual_call_type:
+      return opt_virtual_call_Relocation::spec();
+    case relocInfo::static_call_type:
+      return static_call_Relocation::spec();
+    case relocInfo::runtime_call_w_cp_type:
+      return runtime_call_w_cp_Relocation::spec();
+    case relocInfo::none:
+      return RelocationHolder();
+    default:
+      ShouldNotReachHere();
+      return RelocationHolder();
+    }
+  }
+
+ protected:
+  // creation
+  AddressLiteral() : _address(NULL), _rspec(NULL) {}
+
+ public:
+  AddressLiteral(address addr, RelocationHolder const& rspec)
+    : _address(addr),
+      _rspec(rspec) {}
+
+  // Some constructors to avoid casting at the call site.
+  AddressLiteral(jobject obj, RelocationHolder const& rspec)
+    : _address((address) obj),
+      _rspec(rspec) {}
+
+  AddressLiteral(intptr_t value, RelocationHolder const& rspec)
+    : _address((address) value),
+      _rspec(rspec) {}
+
+  AddressLiteral(address addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+    _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  // Some constructors to avoid casting at the call site.
+  AddressLiteral(address* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+    _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(bool* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(const bool* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(signed char* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(int* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(intptr_t addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(intptr_t* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(oop addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(oop* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(float* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  AddressLiteral(double* addr, relocInfo::relocType rtype = relocInfo::none)
+    : _address((address) addr),
+      _rspec(rspec_from_rtype(rtype, (address) addr)) {}
+
+  intptr_t value() const { return (intptr_t) _address; }
+
+  const relocInfo::relocType rtype() const { return _rspec.type(); }
+  const RelocationHolder&    rspec() const { return _rspec; }
+
+  RelocationHolder rspec(int offset) const {
+    return offset == 0 ? _rspec : _rspec.plus(offset);
+  }
+};
+
+// Convenience classes
+class ExternalAddress: public AddressLiteral {
+ private:
+  static relocInfo::relocType reloc_for_target(address target) {
+    // Sometimes ExternalAddress is used for values which aren't
+    // exactly addresses, like the card table base.
+    // External_word_type can't be used for values in the first page
+    // so just skip the reloc in that case.
+    return external_word_Relocation::can_be_relocated(target) ? relocInfo::external_word_type : relocInfo::none;
+  }
+
+ public:
+  ExternalAddress(address target) : AddressLiteral(target, reloc_for_target(          target)) {}
+  ExternalAddress(oop*    target) : AddressLiteral(target, reloc_for_target((address) target)) {}
+};
+
+// Argument is an abstraction used to represent an outgoing actual
+// argument or an incoming formal parameter, whether it resides in
+// memory or in a register, in a manner consistent with the
+// z/Architecture Application Binary Interface, or ABI. This is often
+// referred to as the native or C calling convention.
+class Argument VALUE_OBJ_CLASS_SPEC {
+ private:
+  int _number;
+  bool _is_in;
+
+ public:
+  enum {
+    // Only 5 registers may contain integer parameters.
+    n_register_parameters = 5,
+    // Can have up to 4 floating registers.
+    n_float_register_parameters = 4
+  };
+
+  // creation
+  Argument(int number, bool is_in) : _number(number), _is_in(is_in) {}
+  Argument(int number) : _number(number) {}
+
+  int number() const { return _number; }
+
+  Argument successor() const { return Argument(number() + 1); }
+
+  // Locating register-based arguments:
+  bool is_register() const { return _number < n_register_parameters; }
+
+  // Locating Floating Point register-based arguments:
+  bool is_float_register() const { return _number < n_float_register_parameters; }
+
+  FloatRegister as_float_register() const {
+    assert(is_float_register(), "must be a register argument");
+    return as_FloatRegister((number() *2) + 1);
+  }
+
+  FloatRegister as_double_register() const {
+    assert(is_float_register(), "must be a register argument");
+    return as_FloatRegister((number() *2));
+  }
+
+  Register as_register() const {
+    assert(is_register(), "must be a register argument");
+    return as_Register(number() + Z_ARG1->encoding());
+  }
+
+  // debugging
+  const char* name() const;
+
+  friend class Assembler;
+};
+
+
+// The z/Architecture Assembler: Pure assembler doing NO optimizations
+// on the instruction level; i.e., what you write is what you get. The
+// Assembler is generating code into a CodeBuffer.
+class Assembler : public AbstractAssembler {
+ protected:
+
+  friend class AbstractAssembler;
+  friend class AddressLiteral;
+
+  // Code patchers need various routines like inv_wdisp().
+  friend class NativeInstruction;
+#ifndef COMPILER2
+  friend class NativeGeneralJump;
+#endif
+  friend class Relocation;
+
+ public:
+
+// Addressing
+
+// address calculation
+#define LA_ZOPC     (unsigned  int)(0x41  << 24)
+#define LAY_ZOPC    (unsigned long)(0xe3L << 40 | 0x71L)
+#define LARL_ZOPC   (unsigned long)(0xc0L << 40 | 0x00L << 32)
+
+
+// Data Transfer
+
+// register to register transfer
+#define LR_ZOPC     (unsigned  int)(24 << 8)
+#define LBR_ZOPC    (unsigned  int)(0xb926 << 16)
+#define LHR_ZOPC    (unsigned  int)(0xb927 << 16)
+#define LGBR_ZOPC   (unsigned  int)(0xb906 << 16)
+#define LGHR_ZOPC   (unsigned  int)(0xb907 << 16)
+#define LGFR_ZOPC   (unsigned  int)(0xb914 << 16)
+#define LGR_ZOPC    (unsigned  int)(0xb904 << 16)
+
+#define LLHR_ZOPC   (unsigned  int)(0xb995 << 16)
+#define LLGCR_ZOPC  (unsigned  int)(0xb984 << 16)
+#define LLGHR_ZOPC  (unsigned  int)(0xb985 << 16)
+#define LLGTR_ZOPC  (unsigned  int)(185 << 24 | 23 << 16)
+#define LLGFR_ZOPC  (unsigned  int)(185 << 24 | 22 << 16)
+
+#define LTR_ZOPC    (unsigned  int)(18 << 8)
+#define LTGFR_ZOPC  (unsigned  int)(185 << 24 | 18 << 16)
+#define LTGR_ZOPC   (unsigned  int)(185 << 24 | 2 << 16)
+
+#define LER_ZOPC    (unsigned  int)(56 << 8)
+#define LEDBR_ZOPC  (unsigned  int)(179 << 24 | 68 << 16)
+#define LEXBR_ZOPC  (unsigned  int)(179 << 24 | 70 << 16)
+#define LDEBR_ZOPC  (unsigned  int)(179 << 24 | 4 << 16)
+#define LDR_ZOPC    (unsigned  int)(40 << 8)
+#define LDXBR_ZOPC  (unsigned  int)(179 << 24 | 69 << 16)
+#define LXEBR_ZOPC  (unsigned  int)(179 << 24 | 6 << 16)
+#define LXDBR_ZOPC  (unsigned  int)(179 << 24 | 5 << 16)
+#define LXR_ZOPC    (unsigned  int)(179 << 24 | 101 << 16)
+#define LTEBR_ZOPC  (unsigned  int)(179 << 24 | 2 << 16)
+#define LTDBR_ZOPC  (unsigned  int)(179 << 24 | 18 << 16)
+#define LTXBR_ZOPC  (unsigned  int)(179 << 24 | 66 << 16)
+
+#define LRVR_ZOPC   (unsigned  int)(0xb91f << 16)
+#define LRVGR_ZOPC  (unsigned  int)(0xb90f << 16)
+
+#define LDGR_ZOPC   (unsigned  int)(0xb3c1 << 16)                // z10
+#define LGDR_ZOPC   (unsigned  int)(0xb3cd << 16)                // z10
+
+#define LOCR_ZOPC   (unsigned  int)(0xb9f2 << 16)                // z196
+#define LOCGR_ZOPC  (unsigned  int)(0xb9e2 << 16)                // z196
+
+// immediate to register transfer
+#define IIHH_ZOPC   (unsigned  int)(165 << 24)
+#define IIHL_ZOPC   (unsigned  int)(165 << 24 | 1 << 16)
+#define IILH_ZOPC   (unsigned  int)(165 << 24 | 2 << 16)
+#define IILL_ZOPC   (unsigned  int)(165 << 24 | 3 << 16)
+#define IIHF_ZOPC   (unsigned long)(0xc0L << 40 | 8L << 32)
+#define IILF_ZOPC   (unsigned long)(0xc0L << 40 | 9L << 32)
+#define LLIHH_ZOPC  (unsigned  int)(165 << 24 | 12 << 16)
+#define LLIHL_ZOPC  (unsigned  int)(165 << 24 | 13 << 16)
+#define LLILH_ZOPC  (unsigned  int)(165 << 24 | 14 << 16)
+#define LLILL_ZOPC  (unsigned  int)(165 << 24 | 15 << 16)
+#define LLIHF_ZOPC  (unsigned long)(0xc0L << 40 | 14L << 32)
+#define LLILF_ZOPC  (unsigned long)(0xc0L << 40 | 15L << 32)
+#define LHI_ZOPC    (unsigned  int)(167 << 24 | 8 << 16)
+#define LGHI_ZOPC   (unsigned  int)(167 << 24 | 9 << 16)
+#define LGFI_ZOPC   (unsigned long)(0xc0L << 40 | 1L << 32)
+
+#define LZER_ZOPC   (unsigned  int)(0xb374 << 16)
+#define LZDR_ZOPC   (unsigned  int)(0xb375 << 16)
+
+// LOAD: memory to register transfer
+#define LB_ZOPC     (unsigned long)(227L << 40 | 118L)
+#define LH_ZOPC     (unsigned  int)(72 << 24)
+#define LHY_ZOPC    (unsigned long)(227L << 40 | 120L)
+#define L_ZOPC      (unsigned  int)(88 << 24)
+#define LY_ZOPC     (unsigned long)(227L << 40 | 88L)
+#define LT_ZOPC     (unsigned long)(0xe3L << 40 | 0x12L)
+#define LGB_ZOPC    (unsigned long)(227L << 40 | 119L)
+#define LGH_ZOPC    (unsigned long)(227L << 40 | 21L)
+#define LGF_ZOPC    (unsigned long)(227L << 40 | 20L)
+#define LG_ZOPC     (unsigned long)(227L << 40 | 4L)
+#define LTG_ZOPC    (unsigned long)(0xe3L << 40 | 0x02L)
+#define LTGF_ZOPC   (unsigned long)(0xe3L << 40 | 0x32L)
+
+#define LLC_ZOPC    (unsigned long)(0xe3L << 40 | 0x94L)
+#define LLH_ZOPC    (unsigned long)(0xe3L << 40 | 0x95L)
+#define LLGT_ZOPC   (unsigned long)(227L << 40 | 23L)
+#define LLGC_ZOPC   (unsigned long)(227L << 40 | 144L)
+#define LLGH_ZOPC   (unsigned long)(227L << 40 | 145L)
+#define LLGF_ZOPC   (unsigned long)(227L << 40 | 22L)
+
+#define IC_ZOPC     (unsigned  int)(0x43  << 24)
+#define ICY_ZOPC    (unsigned long)(0xe3L << 40 | 0x73L)
+#define ICM_ZOPC    (unsigned  int)(0xbf  << 24)
+#define ICMY_ZOPC   (unsigned long)(0xebL << 40 | 0x81L)
+#define ICMH_ZOPC   (unsigned long)(0xebL << 40 | 0x80L)
+
+#define LRVH_ZOPC   (unsigned long)(0xe3L << 40 | 0x1fL)
+#define LRV_ZOPC    (unsigned long)(0xe3L << 40 | 0x1eL)
+#define LRVG_ZOPC   (unsigned long)(0xe3L << 40 | 0x0fL)
+
+
+// LOAD relative: memory to register transfer
+#define LHRL_ZOPC   (unsigned long)(0xc4L << 40 | 0x05L << 32)  // z10
+#define LRL_ZOPC    (unsigned long)(0xc4L << 40 | 0x0dL << 32)  // z10
+#define LGHRL_ZOPC  (unsigned long)(0xc4L << 40 | 0x04L << 32)  // z10
+#define LGFRL_ZOPC  (unsigned long)(0xc4L << 40 | 0x0cL << 32)  // z10
+#define LGRL_ZOPC   (unsigned long)(0xc4L << 40 | 0x08L << 32)  // z10
+
+#define LLHRL_ZOPC  (unsigned long)(0xc4L << 40 | 0x02L << 32)  // z10
+#define LLGHRL_ZOPC (unsigned long)(0xc4L << 40 | 0x06L << 32)  // z10
+#define LLGFRL_ZOPC (unsigned long)(0xc4L << 40 | 0x0eL << 32)  // z10
+
+#define LOC_ZOPC    (unsigned long)(0xebL << 40 | 0xf2L)        // z196
+#define LOCG_ZOPC   (unsigned long)(0xebL << 40 | 0xe2L)        // z196
+
+#define LMG_ZOPC    (unsigned long)(235L << 40 | 4L)
+
+#define LE_ZOPC     (unsigned  int)(0x78 << 24)
+#define LEY_ZOPC    (unsigned long)(237L << 40 | 100L)
+#define LDEB_ZOPC   (unsigned long)(237L << 40 | 4)
+#define LD_ZOPC     (unsigned  int)(0x68 << 24)
+#define LDY_ZOPC    (unsigned long)(237L << 40 | 101L)
+#define LXEB_ZOPC   (unsigned long)(237L << 40 | 6)
+#define LXDB_ZOPC   (unsigned long)(237L << 40 | 5)
+
+// STORE: register to memory transfer
+#define STC_ZOPC    (unsigned  int)(0x42 << 24)
+#define STCY_ZOPC   (unsigned long)(227L << 40 | 114L)
+#define STH_ZOPC    (unsigned  int)(64 << 24)
+#define STHY_ZOPC   (unsigned long)(227L << 40 | 112L)
+#define ST_ZOPC     (unsigned  int)(80 << 24)
+#define STY_ZOPC    (unsigned long)(227L << 40 | 80L)
+#define STG_ZOPC    (unsigned long)(227L << 40 | 36L)
+
+#define STCM_ZOPC   (unsigned long)(0xbeL << 24)
+#define STCMY_ZOPC  (unsigned long)(0xebL << 40 | 0x2dL)
+#define STCMH_ZOPC  (unsigned long)(0xebL << 40 | 0x2cL)
+
+// STORE relative: memory to register transfer
+#define STHRL_ZOPC  (unsigned long)(0xc4L << 40 | 0x07L << 32)  // z10
+#define STRL_ZOPC   (unsigned long)(0xc4L << 40 | 0x0fL << 32)  // z10
+#define STGRL_ZOPC  (unsigned long)(0xc4L << 40 | 0x0bL << 32)  // z10
+
+#define STOC_ZOPC   (unsigned long)(0xebL << 40 | 0xf3L)        // z196
+#define STOCG_ZOPC  (unsigned long)(0xebL << 40 | 0xe3L)        // z196
+
+#define STMG_ZOPC   (unsigned long)(235L << 40 | 36L)
+
+#define STE_ZOPC    (unsigned  int)(0x70 << 24)
+#define STEY_ZOPC   (unsigned long)(237L << 40 | 102L)
+#define STD_ZOPC    (unsigned  int)(0x60 << 24)
+#define STDY_ZOPC   (unsigned long)(237L << 40 | 103L)
+
+// MOVE: immediate to memory transfer
+#define MVHHI_ZOPC  (unsigned long)(0xe5L << 40 | 0x44L << 32)   // z10
+#define MVHI_ZOPC   (unsigned long)(0xe5L << 40 | 0x4cL << 32)   // z10
+#define MVGHI_ZOPC  (unsigned long)(0xe5L << 40 | 0x48L << 32)   // z10
+
+
+//  ALU operations
+
+// Load Positive
+#define LPR_ZOPC    (unsigned  int)(16 << 8)
+#define LPGFR_ZOPC  (unsigned  int)(185 << 24 | 16 << 16)
+#define LPGR_ZOPC   (unsigned  int)(185 << 24)
+#define LPEBR_ZOPC  (unsigned  int)(179 << 24)
+#define LPDBR_ZOPC  (unsigned  int)(179 << 24 | 16 << 16)
+#define LPXBR_ZOPC  (unsigned  int)(179 << 24 | 64 << 16)
+
+// Load Negative
+#define LNR_ZOPC    (unsigned  int)(17 << 8)
+#define LNGFR_ZOPC  (unsigned  int)(185 << 24 | 17 << 16)
+#define LNGR_ZOPC   (unsigned  int)(185 << 24 | 1 << 16)
+#define LNEBR_ZOPC  (unsigned  int)(179 << 24 | 1 << 16)
+#define LNDBR_ZOPC  (unsigned  int)(179 << 24 | 17 << 16)
+#define LNXBR_ZOPC  (unsigned  int)(179 << 24 | 65 << 16)
+
+// Load Complement
+#define LCR_ZOPC    (unsigned  int)(19 << 8)
+#define LCGFR_ZOPC  (unsigned  int)(185 << 24 | 19 << 16)
+#define LCGR_ZOPC   (unsigned  int)(185 << 24 | 3 << 16)
+#define LCEBR_ZOPC  (unsigned  int)(179 << 24 | 3 << 16)
+#define LCDBR_ZOPC  (unsigned  int)(179 << 24 | 19 << 16)
+#define LCXBR_ZOPC  (unsigned  int)(179 << 24 | 67 << 16)
+
+// Add
+// RR, signed
+#define AR_ZOPC     (unsigned  int)(26 << 8)
+#define AGFR_ZOPC   (unsigned  int)(0xb9 << 24 | 0x18 << 16)
+#define AGR_ZOPC    (unsigned  int)(0xb9 << 24 | 0x08 << 16)
+// RRF, signed
+#define ARK_ZOPC    (unsigned  int)(0xb9 << 24 | 0x00f8 << 16)
+#define AGRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00e8 << 16)
+// RI, signed
+#define AHI_ZOPC    (unsigned  int)(167 << 24 | 10 << 16)
+#define AFI_ZOPC    (unsigned long)(0xc2L << 40 | 9L << 32)
+#define AGHI_ZOPC   (unsigned  int)(167 << 24 | 11 << 16)
+#define AGFI_ZOPC   (unsigned long)(0xc2L << 40 | 8L << 32)
+// RIE, signed
+#define AHIK_ZOPC   (unsigned long)(0xecL << 40 | 0x00d8L)
+#define AGHIK_ZOPC  (unsigned long)(0xecL << 40 | 0x00d9L)
+#define AIH_ZOPC    (unsigned long)(0xccL << 40 | 0x08L << 32)
+// RM, signed
+#define AHY_ZOPC    (unsigned long)(227L << 40 | 122L)
+#define A_ZOPC      (unsigned  int)(90 << 24)
+#define AY_ZOPC     (unsigned long)(227L << 40 | 90L)
+#define AGF_ZOPC    (unsigned long)(227L << 40 | 24L)
+#define AG_ZOPC     (unsigned long)(227L << 40 | 8L)
+// In-memory arithmetic (add signed, add logical with signed immediate).
+// MI, signed
+#define ASI_ZOPC    (unsigned long)(0xebL << 40 | 0x6aL)
+#define AGSI_ZOPC   (unsigned long)(0xebL << 40 | 0x7aL)
+
+// RR, Logical
+#define ALR_ZOPC    (unsigned  int)(30 << 8)
+#define ALGFR_ZOPC  (unsigned  int)(185 << 24 | 26 << 16)
+#define ALGR_ZOPC   (unsigned  int)(185 << 24 | 10 << 16)
+#define ALCGR_ZOPC  (unsigned  int)(185 << 24 | 136 << 16)
+// RRF, Logical
+#define ALRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00fa << 16)
+#define ALGRK_ZOPC  (unsigned  int)(0xb9 << 24 | 0x00ea << 16)
+// RI, Logical
+#define ALFI_ZOPC   (unsigned long)(0xc2L << 40 | 0x0bL << 32)
+#define ALGFI_ZOPC  (unsigned long)(0xc2L << 40 | 0x0aL << 32)
+// RIE, Logical
+#define ALHSIK_ZOPC (unsigned long)(0xecL << 40 | 0x00daL)
+#define ALGHSIK_ZOPC (unsigned long)(0xecL << 40 | 0x00dbL)
+// RM, Logical
+#define AL_ZOPC     (unsigned  int)(0x5e << 24)
+#define ALY_ZOPC    (unsigned long)(227L << 40 | 94L)
+#define ALGF_ZOPC   (unsigned long)(227L << 40 | 26L)
+#define ALG_ZOPC    (unsigned long)(227L << 40 | 10L)
+// In-memory arithmetic (add signed, add logical with signed immediate).
+// MI, Logical
+#define ALSI_ZOPC   (unsigned long)(0xebL << 40 | 0x6eL)
+#define ALGSI_ZOPC  (unsigned long)(0xebL << 40 | 0x7eL)
+
+// RR, BFP
+#define AEBR_ZOPC   (unsigned  int)(179 << 24 | 10 << 16)
+#define ADBR_ZOPC   (unsigned  int)(179 << 24 | 26 << 16)
+#define AXBR_ZOPC   (unsigned  int)(179 << 24 | 74 << 16)
+// RM, BFP
+#define AEB_ZOPC    (unsigned long)(237L << 40 | 10)
+#define ADB_ZOPC    (unsigned long)(237L << 40 | 26)
+
+// Subtract
+// RR, signed
+#define SR_ZOPC     (unsigned  int)(27 << 8)
+#define SGFR_ZOPC   (unsigned  int)(185 << 24 | 25 << 16)
+#define SGR_ZOPC    (unsigned  int)(185 << 24 | 9 << 16)
+// RRF, signed
+#define SRK_ZOPC    (unsigned  int)(0xb9 << 24 | 0x00f9 << 16)
+#define SGRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00e9 << 16)
+//   RM, signed
+#define SH_ZOPC     (unsigned  int)(0x4b << 24)
+#define SHY_ZOPC    (unsigned long)(227L << 40 | 123L)
+#define S_ZOPC      (unsigned  int)(0x5B << 24)
+#define SY_ZOPC     (unsigned long)(227L << 40 | 91L)
+#define SGF_ZOPC    (unsigned long)(227L << 40 | 25)
+#define SG_ZOPC     (unsigned long)(227L << 40 | 9)
+// RR, Logical
+#define SLR_ZOPC    (unsigned  int)(31 << 8)
+#define SLGFR_ZOPC  (unsigned  int)(185 << 24 | 27 << 16)
+#define SLGR_ZOPC   (unsigned  int)(185 << 24 | 11 << 16)
+// RIL, Logical
+#define SLFI_ZOPC   (unsigned long)(0xc2L << 40 | 0x05L << 32)
+#define SLGFI_ZOPC  (unsigned long)(0xc2L << 40 | 0x04L << 32)
+// RRF, Logical
+#define SLRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00fb << 16)
+#define SLGRK_ZOPC  (unsigned  int)(0xb9 << 24 | 0x00eb << 16)
+// RM, Logical
+#define SLY_ZOPC    (unsigned long)(227L << 40 | 95L)
+#define SLGF_ZOPC   (unsigned long)(227L << 40 | 27L)
+#define SLG_ZOPC    (unsigned long)(227L << 40 | 11L)
+
+// RR, BFP
+#define SEBR_ZOPC   (unsigned  int)(179 << 24 | 11 << 16)
+#define SDBR_ZOPC   (unsigned  int)(179 << 24 | 27 << 16)
+#define SXBR_ZOPC   (unsigned  int)(179 << 24 | 75 << 16)
+// RM, BFP
+#define SEB_ZOPC    (unsigned long)(237L << 40 | 11)
+#define SDB_ZOPC    (unsigned long)(237L << 40 | 27)
+
+// Multiply
+// RR, signed
+#define MR_ZOPC     (unsigned  int)(28 << 8)
+#define MSR_ZOPC    (unsigned  int)(178 << 24 | 82 << 16)
+#define MSGFR_ZOPC  (unsigned  int)(185 << 24 | 28 << 16)
+#define MSGR_ZOPC   (unsigned  int)(185 << 24 | 12 << 16)
+// RI, signed
+#define MHI_ZOPC    (unsigned  int)(167 << 24 | 12 << 16)
+#define MGHI_ZOPC   (unsigned  int)(167 << 24 | 13 << 16)
+#define MSFI_ZOPC   (unsigned long)(0xc2L << 40 | 0x01L << 32)   // z10
+#define MSGFI_ZOPC  (unsigned long)(0xc2L << 40 | 0x00L << 32)   // z10
+// RM, signed
+#define M_ZOPC      (unsigned  int)(92 << 24)
+#define MS_ZOPC     (unsigned  int)(0x71 << 24)
+#define MHY_ZOPC    (unsigned long)(0xe3L<< 40 | 0x7cL)
+#define MSY_ZOPC    (unsigned long)(227L << 40 | 81L)
+#define MSGF_ZOPC   (unsigned long)(227L << 40 | 28L)
+#define MSG_ZOPC    (unsigned long)(227L << 40 | 12L)
+// RR, unsigned
+#define MLR_ZOPC    (unsigned  int)(185 << 24 | 150 << 16)
+#define MLGR_ZOPC   (unsigned  int)(185 << 24 | 134 << 16)
+// RM, unsigned
+#define ML_ZOPC     (unsigned long)(227L << 40 | 150L)
+#define MLG_ZOPC    (unsigned long)(227L << 40 | 134L)
+
+// RR, BFP
+#define MEEBR_ZOPC  (unsigned  int)(179 << 24 | 23 << 16)
+#define MDEBR_ZOPC  (unsigned  int)(179 << 24 | 12 << 16)
+#define MDBR_ZOPC   (unsigned  int)(179 << 24 | 28 << 16)
+#define MXDBR_ZOPC  (unsigned  int)(179 << 24 | 7 << 16)
+#define MXBR_ZOPC   (unsigned  int)(179 << 24 | 76 << 16)
+// RM, BFP
+#define MEEB_ZOPC   (unsigned long)(237L << 40 | 23)
+#define MDEB_ZOPC   (unsigned long)(237L << 40 | 12)
+#define MDB_ZOPC    (unsigned long)(237L << 40 | 28)
+#define MXDB_ZOPC   (unsigned long)(237L << 40 | 7)
+
+// Divide
+// RR, signed
+#define DSGFR_ZOPC  (unsigned  int)(0xb91d << 16)
+#define DSGR_ZOPC   (unsigned  int)(0xb90d << 16)
+// RM, signed
+#define D_ZOPC      (unsigned  int)(93 << 24)
+#define DSGF_ZOPC   (unsigned long)(227L << 40 | 29L)
+#define DSG_ZOPC    (unsigned long)(227L << 40 | 13L)
+// RR, unsigned
+#define DLR_ZOPC    (unsigned  int)(185 << 24 | 151 << 16)
+#define DLGR_ZOPC   (unsigned  int)(185 << 24 | 135 << 16)
+// RM, unsigned
+#define DL_ZOPC     (unsigned long)(227L << 40 | 151L)
+#define DLG_ZOPC    (unsigned long)(227L << 40 | 135L)
+
+// RR, BFP
+#define DEBR_ZOPC   (unsigned  int)(179 << 24 | 13 << 16)
+#define DDBR_ZOPC   (unsigned  int)(179 << 24 | 29 << 16)
+#define DXBR_ZOPC   (unsigned  int)(179 << 24 | 77 << 16)
+// RM, BFP
+#define DEB_ZOPC    (unsigned long)(237L << 40 | 13)
+#define DDB_ZOPC    (unsigned long)(237L << 40 | 29)
+
+// Square Root
+// RR, BFP
+#define SQEBR_ZOPC  (unsigned  int)(0xb314 << 16)
+#define SQDBR_ZOPC  (unsigned  int)(0xb315 << 16)
+#define SQXBR_ZOPC  (unsigned  int)(0xb316 << 16)
+// RM, BFP
+#define SQEB_ZOPC   (unsigned long)(237L << 40 | 20)
+#define SQDB_ZOPC   (unsigned long)(237L << 40 | 21)
+
+// Compare and Test
+// RR, signed
+#define CR_ZOPC     (unsigned  int)(25 << 8)
+#define CGFR_ZOPC   (unsigned  int)(185 << 24 | 48 << 16)
+#define CGR_ZOPC    (unsigned  int)(185 << 24 | 32 << 16)
+// RI, signed
+#define CHI_ZOPC    (unsigned  int)(167 << 24 | 14 << 16)
+#define CFI_ZOPC    (unsigned long)(0xc2L << 40 | 0xdL << 32)
+#define CGHI_ZOPC   (unsigned  int)(167 << 24 | 15 << 16)
+#define CGFI_ZOPC   (unsigned long)(0xc2L << 40 | 0xcL << 32)
+// RM, signed
+#define CH_ZOPC     (unsigned  int)(0x49 << 24)
+#define CHY_ZOPC    (unsigned long)(227L << 40 | 121L)
+#define C_ZOPC      (unsigned  int)(0x59 << 24)
+#define CY_ZOPC     (unsigned long)(227L << 40 | 89L)
+#define CGF_ZOPC    (unsigned long)(227L << 40 | 48L)
+#define CG_ZOPC     (unsigned long)(227L << 40 | 32L)
+// RR, unsigned
+#define CLR_ZOPC    (unsigned  int)(21 << 8)
+#define CLGFR_ZOPC  (unsigned  int)(185 << 24 | 49 << 16)
+#define CLGR_ZOPC   (unsigned  int)(185 << 24 | 33 << 16)
+// RIL, unsigned
+#define CLFI_ZOPC   (unsigned long)(0xc2L << 40 | 0xfL << 32)
+#define CLGFI_ZOPC  (unsigned long)(0xc2L << 40 | 0xeL << 32)
+// RM, unsigned
+#define CL_ZOPC     (unsigned  int)(0x55 << 24)
+#define CLY_ZOPC    (unsigned long)(227L << 40 | 85L)
+#define CLGF_ZOPC   (unsigned long)(227L << 40 | 49L)
+#define CLG_ZOPC    (unsigned long)(227L << 40 | 33L)
+// RI, unsigned
+#define TMHH_ZOPC   (unsigned  int)(167 << 24 | 2 << 16)
+#define TMHL_ZOPC   (unsigned  int)(167 << 24 | 3 << 16)
+#define TMLH_ZOPC   (unsigned  int)(167 << 24)
+#define TMLL_ZOPC   (unsigned  int)(167 << 24 | 1 << 16)
+
+// RR, BFP
+#define CEBR_ZOPC   (unsigned  int)(179 << 24 | 9 << 16)
+#define CDBR_ZOPC   (unsigned  int)(179 << 24 | 25 << 16)
+#define CXBR_ZOPC   (unsigned  int)(179 << 24 | 73 << 16)
+// RM, BFP
+#define CEB_ZOPC    (unsigned long)(237L << 40 | 9)
+#define CDB_ZOPC    (unsigned long)(237L << 40 | 25)
+
+// Shift
+// arithmetic
+#define SLA_ZOPC    (unsigned  int)(139 << 24)
+#define SLAG_ZOPC   (unsigned long)(235L << 40 | 11L)
+#define SRA_ZOPC    (unsigned  int)(138 << 24)
+#define SRAG_ZOPC   (unsigned long)(235L << 40 | 10L)
+// logical
+#define SLL_ZOPC    (unsigned  int)(137 << 24)
+#define SLLG_ZOPC   (unsigned long)(235L << 40 | 13L)
+#define SRL_ZOPC    (unsigned  int)(136 << 24)
+#define SRLG_ZOPC   (unsigned long)(235L << 40 | 12L)
+
+// Rotate, then AND/XOR/OR/insert
+// rotate
+#define RLL_ZOPC    (unsigned long)(0xebL << 40 | 0x1dL)         // z10
+#define RLLG_ZOPC   (unsigned long)(0xebL << 40 | 0x1cL)         // z10
+// rotate and {AND|XOR|OR|INS}
+#define RNSBG_ZOPC  (unsigned long)(0xecL << 40 | 0x54L)         // z196
+#define RXSBG_ZOPC  (unsigned long)(0xecL << 40 | 0x57L)         // z196
+#define ROSBG_ZOPC  (unsigned long)(0xecL << 40 | 0x56L)         // z196
+#define RISBG_ZOPC  (unsigned long)(0xecL << 40 | 0x55L)         // z196
+
+// AND
+// RR, signed
+#define NR_ZOPC     (unsigned  int)(20 << 8)
+#define NGR_ZOPC    (unsigned  int)(185 << 24 | 128 << 16)
+// RRF, signed
+#define NRK_ZOPC    (unsigned  int)(0xb9 << 24 | 0x00f4 << 16)
+#define NGRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00e4 << 16)
+// RI, signed
+#define NIHH_ZOPC   (unsigned  int)(165 << 24 | 4 << 16)
+#define NIHL_ZOPC   (unsigned  int)(165 << 24 | 5 << 16)
+#define NILH_ZOPC   (unsigned  int)(165 << 24 | 6 << 16)
+#define NILL_ZOPC   (unsigned  int)(165 << 24 | 7 << 16)
+#define NIHF_ZOPC   (unsigned long)(0xc0L << 40 | 10L << 32)
+#define NILF_ZOPC   (unsigned long)(0xc0L << 40 | 11L << 32)
+// RM, signed
+#define N_ZOPC      (unsigned  int)(0x54 << 24)
+#define NY_ZOPC     (unsigned long)(227L << 40 | 84L)
+#define NG_ZOPC     (unsigned long)(227L << 40 | 128L)
+
+// OR
+// RR, signed
+#define OR_ZOPC     (unsigned  int)(22 << 8)
+#define OGR_ZOPC    (unsigned  int)(185 << 24 | 129 << 16)
+// RRF, signed
+#define ORK_ZOPC    (unsigned  int)(0xb9 << 24 | 0x00f6 << 16)
+#define OGRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00e6 << 16)
+// RI, signed
+#define OIHH_ZOPC   (unsigned  int)(165 << 24 | 8 << 16)
+#define OIHL_ZOPC   (unsigned  int)(165 << 24 | 9 << 16)
+#define OILH_ZOPC   (unsigned  int)(165 << 24 | 10 << 16)
+#define OILL_ZOPC   (unsigned  int)(165 << 24 | 11 << 16)
+#define OIHF_ZOPC   (unsigned long)(0xc0L << 40 | 12L << 32)
+#define OILF_ZOPC   (unsigned long)(0xc0L << 40 | 13L << 32)
+// RM, signed
+#define O_ZOPC      (unsigned  int)(0x56 << 24)
+#define OY_ZOPC     (unsigned long)(227L << 40 | 86L)
+#define OG_ZOPC     (unsigned long)(227L << 40 | 129L)
+
+// XOR
+// RR, signed
+#define XR_ZOPC     (unsigned  int)(23 << 8)
+#define XGR_ZOPC    (unsigned  int)(185 << 24 | 130 << 16)
+// RRF, signed
+#define XRK_ZOPC    (unsigned  int)(0xb9 << 24 | 0x00f7 << 16)
+#define XGRK_ZOPC   (unsigned  int)(0xb9 << 24 | 0x00e7 << 16)
+// RI, signed
+#define XIHF_ZOPC   (unsigned long)(0xc0L << 40 | 6L << 32)
+#define XILF_ZOPC   (unsigned long)(0xc0L << 40 | 7L << 32)
+// RM, signed
+#define X_ZOPC      (unsigned  int)(0x57 << 24)
+#define XY_ZOPC     (unsigned long)(227L << 40 | 87L)
+#define XG_ZOPC     (unsigned long)(227L << 40 | 130L)
+
+
+// Data Conversion
+
+// INT to BFP
+#define CEFBR_ZOPC  (unsigned  int)(179 << 24 | 148 << 16)
+#define CDFBR_ZOPC  (unsigned  int)(179 << 24 | 149 << 16)
+#define CXFBR_ZOPC  (unsigned  int)(179 << 24 | 150 << 16)
+#define CEGBR_ZOPC  (unsigned  int)(179 << 24 | 164 << 16)
+#define CDGBR_ZOPC  (unsigned  int)(179 << 24 | 165 << 16)
+#define CXGBR_ZOPC  (unsigned  int)(179 << 24 | 166 << 16)
+// BFP to INT
+#define CFEBR_ZOPC  (unsigned  int)(179 << 24 | 152 << 16)
+#define CFDBR_ZOPC  (unsigned  int)(179 << 24 | 153 << 16)
+#define CFXBR_ZOPC  (unsigned  int)(179 << 24 | 154 << 16)
+#define CGEBR_ZOPC  (unsigned  int)(179 << 24 | 168 << 16)
+#define CGDBR_ZOPC  (unsigned  int)(179 << 24 | 169 << 16)
+#define CGXBR_ZOPC  (unsigned  int)(179 << 24 | 170 << 16)
+// INT to DEC
+#define CVD_ZOPC    (unsigned  int)(0x4e << 24)
+#define CVDY_ZOPC   (unsigned long)(0xe3L << 40 | 0x26L)
+#define CVDG_ZOPC   (unsigned long)(0xe3L << 40 | 0x2eL)
+
+
+// BFP Control
+
+#define SRNM_ZOPC   (unsigned  int)(178 << 24 | 153 << 16)
+#define EFPC_ZOPC   (unsigned  int)(179 << 24 | 140 << 16)
+#define SFPC_ZOPC   (unsigned  int)(179 << 24 | 132 << 16)
+#define STFPC_ZOPC  (unsigned  int)(178 << 24 | 156 << 16)
+#define LFPC_ZOPC   (unsigned  int)(178 << 24 | 157 << 16)
+
+
+// Branch Instructions
+
+// Register
+#define BCR_ZOPC    (unsigned  int)(7 << 8)
+#define BALR_ZOPC   (unsigned  int)(5 << 8)
+#define BASR_ZOPC   (unsigned  int)(13 << 8)
+#define BCTGR_ZOPC  (unsigned long)(0xb946 << 16)
+// Absolute
+#define BC_ZOPC     (unsigned  int)(71 << 24)
+#define BAL_ZOPC    (unsigned  int)(69 << 24)
+#define BAS_ZOPC    (unsigned  int)(77 << 24)
+#define BXH_ZOPC    (unsigned  int)(134 << 24)
+#define BXHG_ZOPC   (unsigned long)(235L << 40 | 68)
+// Relative
+#define BRC_ZOPC    (unsigned  int)(167 << 24 | 4 << 16)
+#define BRCL_ZOPC   (unsigned long)(192L << 40 | 4L << 32)
+#define BRAS_ZOPC   (unsigned  int)(167 << 24 | 5 << 16)
+#define BRASL_ZOPC  (unsigned long)(192L << 40 | 5L << 32)
+#define BRCT_ZOPC   (unsigned  int)(167 << 24 | 6 << 16)
+#define BRCTG_ZOPC  (unsigned  int)(167 << 24 | 7 << 16)
+#define BRXH_ZOPC   (unsigned  int)(132 << 24)
+#define BRXHG_ZOPC  (unsigned long)(236L << 40 | 68)
+#define BRXLE_ZOPC  (unsigned  int)(133 << 24)
+#define BRXLG_ZOPC  (unsigned long)(236L << 40 | 69)
+
+
+// Compare and Branch Instructions
+
+// signed comp reg/reg, branch Absolute
+#define CRB_ZOPC    (unsigned long)(0xecL << 40 | 0xf6L)         // z10
+#define CGRB_ZOPC   (unsigned long)(0xecL << 40 | 0xe4L)         // z10
+// signed comp reg/reg, branch Relative
+#define CRJ_ZOPC    (unsigned long)(0xecL << 40 | 0x76L)         // z10
+#define CGRJ_ZOPC   (unsigned long)(0xecL << 40 | 0x64L)         // z10
+// signed comp reg/imm, branch absolute
+#define CIB_ZOPC    (unsigned long)(0xecL << 40 | 0xfeL)         // z10
+#define CGIB_ZOPC   (unsigned long)(0xecL << 40 | 0xfcL)         // z10
+// signed comp reg/imm, branch relative
+#define CIJ_ZOPC    (unsigned long)(0xecL << 40 | 0x7eL)         // z10
+#define CGIJ_ZOPC   (unsigned long)(0xecL << 40 | 0x7cL)         // z10
+
+// unsigned comp reg/reg, branch Absolute
+#define CLRB_ZOPC   (unsigned long)(0xecL << 40 | 0xf7L)         // z10
+#define CLGRB_ZOPC  (unsigned long)(0xecL << 40 | 0xe5L)         // z10
+// unsigned comp reg/reg, branch Relative
+#define CLRJ_ZOPC   (unsigned long)(0xecL << 40 | 0x77L)         // z10
+#define CLGRJ_ZOPC  (unsigned long)(0xecL << 40 | 0x65L)         // z10
+// unsigned comp reg/imm, branch absolute
+#define CLIB_ZOPC   (unsigned long)(0xecL << 40 | 0xffL)         // z10
+#define CLGIB_ZOPC  (unsigned long)(0xecL << 40 | 0xfdL)         // z10
+// unsigned comp reg/imm, branch relative
+#define CLIJ_ZOPC   (unsigned long)(0xecL << 40 | 0x7fL)         // z10
+#define CLGIJ_ZOPC  (unsigned long)(0xecL << 40 | 0x7dL)         // z10
+
+// comp reg/reg, trap
+#define CRT_ZOPC    (unsigned  int)(0xb972 << 16)                // z10
+#define CGRT_ZOPC   (unsigned  int)(0xb960 << 16)                // z10
+#define CLRT_ZOPC   (unsigned  int)(0xb973 << 16)                // z10
+#define CLGRT_ZOPC  (unsigned  int)(0xb961 << 16)                // z10
+// comp reg/imm, trap
+#define CIT_ZOPC    (unsigned long)(0xecL << 40 | 0x72L)         // z10
+#define CGIT_ZOPC   (unsigned long)(0xecL << 40 | 0x70L)         // z10
+#define CLFIT_ZOPC  (unsigned long)(0xecL << 40 | 0x73L)         // z10
+#define CLGIT_ZOPC  (unsigned long)(0xecL << 40 | 0x71L)         // z10
+
+
+// Direct Memory Operations
+
+// Compare
+#define CLI_ZOPC    (unsigned  int)(0x95  << 24)
+#define CLIY_ZOPC   (unsigned long)(0xebL << 40 | 0x55L)
+#define CLC_ZOPC    (unsigned long)(0xd5L << 40)
+#define CLCL_ZOPC   (unsigned  int)(0x0f  <<  8)
+#define CLCLE_ZOPC  (unsigned  int)(0xa9  << 24)
+#define CLCLU_ZOPC  (unsigned long)(0xebL << 40 | 0x8fL)
+
+// Move
+#define MVI_ZOPC    (unsigned  int)(0x92  << 24)
+#define MVIY_ZOPC   (unsigned long)(0xebL << 40 | 0x52L)
+#define MVC_ZOPC    (unsigned long)(0xd2L << 40)
+#define MVCL_ZOPC   (unsigned  int)(0x0e  <<  8)
+#define MVCLE_ZOPC  (unsigned  int)(0xa8  << 24)
+
+// Test
+#define TM_ZOPC     (unsigned  int)(0x91  << 24)
+#define TMY_ZOPC    (unsigned long)(0xebL << 40 | 0x51L)
+
+// AND
+#define NI_ZOPC     (unsigned  int)(0x94  << 24)
+#define NIY_ZOPC    (unsigned long)(0xebL << 40 | 0x54L)
+#define NC_ZOPC     (unsigned long)(0xd4L << 40)
+
+// OR
+#define OI_ZOPC     (unsigned  int)(0x96  << 24)
+#define OIY_ZOPC    (unsigned long)(0xebL << 40 | 0x56L)
+#define OC_ZOPC     (unsigned long)(0xd6L << 40)
+
+// XOR
+#define XI_ZOPC     (unsigned  int)(0x97  << 24)
+#define XIY_ZOPC    (unsigned long)(0xebL << 40 | 0x57L)
+#define XC_ZOPC     (unsigned long)(0xd7L << 40)
+
+// Search String
+#define SRST_ZOPC   (unsigned  int)(178 << 24 | 94 << 16)
+#define SRSTU_ZOPC  (unsigned  int)(185 << 24 | 190 << 16)
+
+// Translate characters
+#define TROO_ZOPC   (unsigned  int)(0xb9 << 24 | 0x93 << 16)
+#define TROT_ZOPC   (unsigned  int)(0xb9 << 24 | 0x92 << 16)
+#define TRTO_ZOPC   (unsigned  int)(0xb9 << 24 | 0x91 << 16)
+#define TRTT_ZOPC   (unsigned  int)(0xb9 << 24 | 0x90 << 16)
+
+
+// Miscellaneous Operations
+
+// Execute
+#define EX_ZOPC     (unsigned  int)(68L << 24)
+#define EXRL_ZOPC   (unsigned long)(0xc6L << 40 | 0x00L << 32)  // z10
+
+// Compare and Swap
+#define CS_ZOPC     (unsigned  int)(0xba << 24)
+#define CSY_ZOPC    (unsigned long)(0xebL << 40 | 0x14L)
+#define CSG_ZOPC    (unsigned long)(0xebL << 40 | 0x30L)
+
+// Interlocked-Update
+#define LAA_ZOPC    (unsigned long)(0xebL << 40 | 0xf8L)         // z196
+#define LAAG_ZOPC   (unsigned long)(0xebL << 40 | 0xe8L)         // z196
+#define LAAL_ZOPC   (unsigned long)(0xebL << 40 | 0xfaL)         // z196
+#define LAALG_ZOPC  (unsigned long)(0xebL << 40 | 0xeaL)         // z196
+#define LAN_ZOPC    (unsigned long)(0xebL << 40 | 0xf4L)         // z196
+#define LANG_ZOPC   (unsigned long)(0xebL << 40 | 0xe4L)         // z196
+#define LAX_ZOPC    (unsigned long)(0xebL << 40 | 0xf7L)         // z196
+#define LAXG_ZOPC   (unsigned long)(0xebL << 40 | 0xe7L)         // z196
+#define LAO_ZOPC    (unsigned long)(0xebL << 40 | 0xf6L)         // z196
+#define LAOG_ZOPC   (unsigned long)(0xebL << 40 | 0xe6L)         // z196
+
+// System Functions
+#define STCK_ZOPC   (unsigned  int)(0xb2 << 24 | 0x05 << 16)
+#define STCKF_ZOPC  (unsigned  int)(0xb2 << 24 | 0x7c << 16)
+#define STFLE_ZOPC  (unsigned  int)(0xb2 << 24 | 0xb0 << 16)
+#define ECTG_ZOPC   (unsigned long)(0xc8L <<40 | 0x01L << 32)    // z10
+#define ECAG_ZOPC   (unsigned long)(0xebL <<40 | 0x4cL)          // z10
+
+// Execution Prediction
+#define PFD_ZOPC    (unsigned long)(0xe3L <<40 | 0x36L)          // z10
+#define PFDRL_ZOPC  (unsigned long)(0xc6L <<40 | 0x02L << 32)    // z10
+#define BPP_ZOPC    (unsigned long)(0xc7L <<40)                  // branch prediction preload  -- EC12
+#define BPRP_ZOPC   (unsigned long)(0xc5L <<40)                  // branch prediction preload  -- EC12
+
+// Transaction Control
+#define TBEGIN_ZOPC  (unsigned long)(0xe560L << 32)              // tx begin                   -- EC12
+#define TBEGINC_ZOPC (unsigned long)(0xe561L << 32)              // tx begin (constrained)     -- EC12
+#define TEND_ZOPC    (unsigned  int)(0xb2f8  << 16)              // tx end                     -- EC12
+#define TABORT_ZOPC  (unsigned  int)(0xb2fc  << 16)              // tx abort                   -- EC12
+#define ETND_ZOPC    (unsigned  int)(0xb2ec  << 16)              // tx nesting depth           -- EC12
+#define PPA_ZOPC     (unsigned  int)(0xb2e8  << 16)              // tx processor assist        -- EC12
+
+// Crypto and Checksum
+#define CKSM_ZOPC   (unsigned  int)(0xb2 << 24 | 0x41 << 16)     // checksum. This is NOT CRC32
+#define KM_ZOPC     (unsigned  int)(0xb9 << 24 | 0x2e << 16)     // cipher
+#define KMC_ZOPC    (unsigned  int)(0xb9 << 24 | 0x2f << 16)     // cipher
+#define KIMD_ZOPC   (unsigned  int)(0xb9 << 24 | 0x3e << 16)     // SHA (msg digest)
+#define KLMD_ZOPC   (unsigned  int)(0xb9 << 24 | 0x3f << 16)     // SHA (msg digest)
+#define KMAC_ZOPC   (unsigned  int)(0xb9 << 24 | 0x1e << 16)     // Message Authentication Code
+
+// Various
+#define TCEB_ZOPC   (unsigned long)(237L << 40 | 16)
+#define TCDB_ZOPC   (unsigned long)(237L << 40 | 17)
+#define TAM_ZOPC    (unsigned long)(267)
+
+#define FLOGR_ZOPC  (unsigned  int)(0xb9 << 24 | 0x83 << 16)
+#define POPCNT_ZOPC (unsigned  int)(0xb9e1 << 16)
+#define AHHHR_ZOPC  (unsigned  int)(0xb9c8 << 16)
+#define AHHLR_ZOPC  (unsigned  int)(0xb9d8 << 16)
+
+
+// OpCode field masks
+
+#define RI_MASK     (unsigned  int)(0xff  << 24 | 0x0f << 16)
+#define RRE_MASK    (unsigned  int)(0xff  << 24 | 0xff << 16)
+#define RSI_MASK    (unsigned  int)(0xff  << 24)
+#define RIE_MASK    (unsigned long)(0xffL << 40 | 0xffL)
+#define RIL_MASK    (unsigned long)(0xffL << 40 | 0x0fL << 32)
+
+#define BASR_MASK   (unsigned  int)(0xff << 8)
+#define BCR_MASK    (unsigned  int)(0xff << 8)
+#define BRC_MASK    (unsigned  int)(0xff << 24 | 0x0f << 16)
+#define LGHI_MASK   (unsigned  int)(0xff << 24 | 0x0f << 16)
+#define LLI_MASK    (unsigned  int)(0xff << 24 | 0x0f << 16)
+#define II_MASK     (unsigned  int)(0xff << 24 | 0x0f << 16)
+#define LLIF_MASK   (unsigned long)(0xffL << 40 | 0x0fL << 32)
+#define IIF_MASK    (unsigned long)(0xffL << 40 | 0x0fL << 32)
+#define BRASL_MASK  (unsigned long)(0xffL << 40 | 0x0fL << 32)
+#define TM_MASK     (unsigned  int)(0xff << 24)
+#define TMY_MASK    (unsigned long)(0xffL << 40 | 0xffL)
+#define LB_MASK     (unsigned long)(0xffL << 40 | 0xffL)
+#define LH_MASK     (unsigned int)(0xff << 24)
+#define L_MASK      (unsigned int)(0xff << 24)
+#define LY_MASK     (unsigned long)(0xffL << 40 | 0xffL)
+#define LG_MASK     (unsigned long)(0xffL << 40 | 0xffL)
+#define LLGH_MASK   (unsigned long)(0xffL << 40 | 0xffL)
+#define LLGF_MASK   (unsigned long)(0xffL << 40 | 0xffL)
+#define SLAG_MASK   (unsigned long)(0xffL << 40 | 0xffL)
+#define LARL_MASK   (unsigned long)(0xff0fL << 32)
+#define LGRL_MASK   (unsigned long)(0xff0fL << 32)
+#define LE_MASK     (unsigned int)(0xff << 24)
+#define LD_MASK     (unsigned int)(0xff << 24)
+#define ST_MASK     (unsigned int)(0xff << 24)
+#define STC_MASK    (unsigned int)(0xff << 24)
+#define STG_MASK    (unsigned long)(0xffL << 40 | 0xffL)
+#define STH_MASK    (unsigned int)(0xff << 24)
+#define STE_MASK    (unsigned int)(0xff << 24)
+#define STD_MASK    (unsigned int)(0xff << 24)
+#define CMPBRANCH_MASK (unsigned long)(0xffL << 40 | 0xffL)
+#define REL_LONG_MASK  (unsigned long)(0xff0fL << 32)
+
+ public:
+  // Condition code masks. Details:
+  // - Mask bit#3 must be zero for all compare and branch/trap instructions to ensure
+  //   future compatibility.
+  // - For all arithmetic instructions which set the condition code, mask bit#3
+  //   indicates overflow ("unordered" in float operations).
+  // - "unordered" float comparison results have to be treated as low.
+  // - When overflow/unordered is detected, none of the branch conditions is true,
+  //   except for bcondOverflow/bcondNotOrdered and bcondAlways.
+  // - For INT comparisons, the inverse condition can be calculated as (14-cond).
+  // - For FLOAT comparisons, the inverse condition can be calculated as (15-cond).
+  enum branch_condition {
+    bcondNever       =  0,
+    bcondAlways      = 15,
+
+    // Specific names. Make use of lightweight sync.
+    // Full and lightweight sync operation.
+    bcondFullSync    = 15,
+    bcondLightSync   = 14,
+    bcondNop         =  0,
+
+    // arithmetic compare instructions
+    // arithmetic load and test, insert instructions
+    // Mask bit#3 must be zero for future compatibility.
+    bcondEqual       =  8,
+    bcondNotEqual    =  6,
+    bcondLow         =  4,
+    bcondNotLow      = 10,
+    bcondHigh        =  2,
+    bcondNotHigh     = 12,
+    // arithmetic calculation instructions
+    // Mask bit#3 indicates overflow if detected by instr.
+    // Mask bit#3 = 0 (overflow is not handled by compiler).
+    bcondOverflow    =  1,
+    bcondNotOverflow = 14,
+    bcondZero        =  bcondEqual,
+    bcondNotZero     =  bcondNotEqual,
+    bcondNegative    =  bcondLow,
+    bcondNotNegative =  bcondNotLow,
+    bcondPositive    =  bcondHigh,
+    bcondNotPositive =  bcondNotHigh,
+    bcondNotOrdered  =  1,  // float comparisons
+    bcondOrdered     = 14,  // float comparisons
+    bcondLowOrNotOrdered  =  bcondLow|bcondNotOrdered,  // float comparisons
+    bcondHighOrNotOrdered =  bcondHigh|bcondNotOrdered, // float comparisons
+    // unsigned arithmetic calculation instructions
+    // Mask bit#0 is not used by these instructions.
+    // There is no indication of overflow for these instr.
+    bcondLogZero             =  2,
+    bcondLogNotZero          =  5,
+    bcondLogNotZero_Borrow   =  4,
+    bcondLogNotZero_NoBorrow =  1,
+    // string search instructions
+    bcondFound       =  4,
+    bcondNotFound    =  2,
+    bcondInterrupted =  1,
+    // bit test instructions
+    bcondAllZero     =  8,
+    bcondMixed       =  6,
+    bcondAllOne      =  1,
+    bcondNotAllZero  =  7 // for tmll
+  };
+
+  enum Condition {
+    // z/Architecture
+    negative         = 0,
+    less             = 0,
+    positive         = 1,
+    greater          = 1,
+    zero             = 2,
+    equal            = 2,
+    summary_overflow = 3,
+  };
+
+  // Rounding mode for float-2-int conversions.
+  enum RoundingMode {
+    current_mode      = 0,   // Mode taken from FPC register.
+    biased_to_nearest = 1,
+    to_nearest        = 4,
+    to_zero           = 5,
+    to_plus_infinity  = 6,
+    to_minus_infinity = 7
+  };
+
+  // Inverse condition code, i.e. determine "15 - cc" for a given condition code cc.
+  static branch_condition inverse_condition(branch_condition cc);
+  static branch_condition inverse_float_condition(branch_condition cc);
+
+
+  //-----------------------------------------------
+  // instruction property getter methods
+  //-----------------------------------------------
+
+  // Calculate length of instruction.
+  static int instr_len(unsigned char *instr);
+
+  // Longest instructions are 6 bytes on z/Architecture.
+  static int instr_maxlen() { return 6; }
+
+  // Average instruction is 4 bytes on z/Architecture (just a guess).
+  static int instr_avglen() { return 4; }
+
+  // Shortest instructions are 2 bytes on z/Architecture.
+  static int instr_minlen() { return 2; }
+
+  // Move instruction at pc right-justified into passed long int.
+  // Return instr len in bytes as function result.
+  static unsigned int get_instruction(unsigned char *pc, unsigned long *instr);
+
+  // Move instruction in passed (long int) into storage at pc.
+  // This code is _NOT_ MT-safe!!
+  static void set_instruction(unsigned char *pc, unsigned long instr, unsigned int len) {
+    memcpy(pc, ((unsigned char *)&instr)+sizeof(unsigned long)-len, len);
+  }
+
+
+  //------------------------------------------
+  // instruction field test methods
+  //------------------------------------------
+
+  // Only used once in s390.ad to implement Matcher::is_short_branch_offset().
+  static bool is_within_range_of_RelAddr16(address target, address origin) {
+    return RelAddr::is_in_range_of_RelAddr16(target, origin);
+  }
+
+
+  //----------------------------------
+  // some diagnostic output
+  //----------------------------------
+
+  static void print_dbg_msg(outputStream* out, unsigned long inst, const char* msg, int ilen) PRODUCT_RETURN;
+  static void dump_code_range(outputStream* out, address pc, const unsigned int range, const char* msg = " ") PRODUCT_RETURN;
+
+ protected:
+
+  //-------------------------------------------------------
+  // instruction field helper methods (internal)
+  //-------------------------------------------------------
+
+  // Return a mask of 1s between hi_bit and lo_bit (inclusive).
+  static long fmask(unsigned int hi_bit, unsigned int lo_bit) {
+    assert(hi_bit >= lo_bit && hi_bit < 48, "bad bits");
+    return ((1L<<(hi_bit-lo_bit+1)) - 1) << lo_bit;
+  }
+
+  // extract u_field
+  // unsigned value
+  static long inv_u_field(long x, int hi_bit, int lo_bit) {
+    return (x & fmask(hi_bit, lo_bit)) >> lo_bit;
+  }
+
+  // extract s_field
+  // Signed value, may need sign extension.
+  static long inv_s_field(long x, int hi_bit, int lo_bit) {
+    x = inv_u_field(x, hi_bit, lo_bit);
+    // Highest extracted bit set -> sign extension.
+    return (x >= (1L<<(hi_bit-lo_bit)) ? x | ((-1L)<<(hi_bit-lo_bit)) : x);
+  }
+
+  // Extract primary opcode from instruction.
+  static int z_inv_op(int  x) { return inv_u_field(x, 31, 24); }
+  static int z_inv_op(long x) { return inv_u_field(x, 47, 40); }
+
+  static int inv_reg( long x, int s, int len) { return inv_u_field(x, (len-s)-1, (len-s)-4); }  // Regs are encoded in 4 bits.
+  static int inv_mask(long x, int s, int len) { return inv_u_field(x, (len-s)-1, (len-s)-8); }  // Mask is 8 bits long.
+  static int inv_simm16_48(long x) { return (inv_s_field(x, 31, 16)); }                         // 6-byte instructions only
+  static int inv_simm16(long x)    { return (inv_s_field(x, 15,  0)); }                         // 4-byte instructions only
+  static int inv_simm20(long x)    { return (inv_u_field(x, 27, 16) |                           // 6-byte instructions only
+                                             inv_s_field(x, 15, 8)<<12); }
+  static int inv_simm32(long x)    { return (inv_s_field(x, 31,  0)); }                         // 6-byte instructions only
+  static int inv_uimm12(long x)    { return (inv_u_field(x, 11,  0)); }                         // 4-byte instructions only
+
+  // Encode u_field from long value.
+  static long u_field(long x, int hi_bit, int lo_bit) {
+    long r = x << lo_bit;
+    assert((r & ~fmask(hi_bit, lo_bit))   == 0, "value out of range");
+    assert(inv_u_field(r, hi_bit, lo_bit) == x, "just checking");
+    return r;
+  }
+
+ public:
+
+  //--------------------------------------------------
+  // instruction field construction methods
+  //--------------------------------------------------
+
+  // Compute relative address (32 bit) for branch.
+  // Only used once in nativeInst_s390.cpp.
+  static intptr_t z_pcrel_off(address dest, address pc) {
+    return RelAddr::pcrel_off32(dest, pc);
+  }
+
+  // Extract 20-bit signed displacement.
+  // Only used in disassembler_s390.cpp for temp enhancements.
+  static int inv_simm20_xx(address iLoc) {
+    unsigned long instr = 0;
+    unsigned long iLen  = get_instruction(iLoc, &instr);
+    return inv_simm20(instr);
+  }
+
+  // unsigned immediate, in low bits, nbits long
+  static long uimm(long x, int nbits) {
+    assert(Immediate::is_uimm(x, nbits), "unsigned constant out of range");
+    return x & fmask(nbits - 1, 0);
+  }
+
+  // Cast '1' to long to avoid sign extension if nbits = 32.
+  // signed immediate, in low bits, nbits long
+  static long simm(long x, int nbits) {
+    assert(Immediate::is_simm(x, nbits), "value out of range");
+    return x & fmask(nbits - 1, 0);
+  }
+
+  static long imm(int64_t x, int nbits) {
+    // Assert that x can be represented with nbits bits ignoring the sign bits,
+    // i.e. the more higher bits should all be 0 or 1.
+    assert((x >> nbits) == 0 || (x >> nbits) == -1, "value out of range");
+    return x & fmask(nbits-1, 0);
+  }
+
+  // A 20-bit displacement is only in instructions of the
+  // RSY, RXY, or SIY format. In these instructions, the D
+  // field consists of a DL (low) field in bit positions 20-31
+  // and of a DH (high) field in bit positions 32-39. The
+  // value of the displacement is formed by appending the
+  // contents of the DH field to the left of the contents of
+  // the DL field.
+  static long simm20(int64_t ui20) {
+    assert(Immediate::is_simm(ui20, 20), "value out of range");
+    return ( ((ui20        & 0xfffL) << (48-32)) |  // DL
+            (((ui20 >> 12) &  0xffL) << (48-40)));  // DH
+  }
+
+  static long reg(Register r, int s, int len)  { return u_field(r->encoding(), (len-s)-1, (len-s)-4); }
+  static long reg(int r, int s, int len)       { return u_field(r,             (len-s)-1, (len-s)-4); }
+  static long regt(Register r, int s, int len) { return reg(r, s, len); }
+  static long regz(Register r, int s, int len) { assert(r != Z_R0, "cannot use register R0 in memory access"); return reg(r, s, len); }
+
+  static long uimm4( int64_t ui4,  int s, int len) { return uimm(ui4,   4) << (len-s-4);  }
+  static long uimm6( int64_t ui6,  int s, int len) { return uimm(ui6,   6) << (len-s-6);  }
+  static long uimm8( int64_t ui8,  int s, int len) { return uimm(ui8,   8) << (len-s-8);  }
+  static long uimm12(int64_t ui12, int s, int len) { return uimm(ui12, 12) << (len-s-12); }
+  static long uimm16(int64_t ui16, int s, int len) { return uimm(ui16, 16) << (len-s-16); }
+  static long uimm32(int64_t ui32, int s, int len) { return uimm((unsigned)ui32, 32) << (len-s-32); } // prevent sign extension
+
+  static long simm8( int64_t si8,  int s, int len) { return simm(si8,   8) << (len-s-8);  }
+  static long simm12(int64_t si12, int s, int len) { return simm(si12, 12) << (len-s-12); }
+  static long simm16(int64_t si16, int s, int len) { return simm(si16, 16) << (len-s-16); }
+  static long simm24(int64_t si24, int s, int len) { return simm(si24, 24) << (len-s-24); }
+  static long simm32(int64_t si32, int s, int len) { return simm(si32, 32) << (len-s-32); }
+
+  static long imm8( int64_t i8,  int s, int len)   { return imm(i8,   8) << (len-s-8);  }
+  static long imm12(int64_t i12, int s, int len)   { return imm(i12, 12) << (len-s-12); }
+  static long imm16(int64_t i16, int s, int len)   { return imm(i16, 16) << (len-s-16); }
+  static long imm24(int64_t i24, int s, int len)   { return imm(i24, 24) << (len-s-24); }
+  static long imm32(int64_t i32, int s, int len)   { return imm(i32, 32) << (len-s-32); }
+
+  static long fregt(FloatRegister r, int s, int len) { return freg(r,s,len); }
+  static long freg( FloatRegister r, int s, int len) { return u_field(r->encoding(), (len-s)-1, (len-s)-4); }
+
+  // Rounding mode for float-2-int conversions.
+  static long rounding_mode(RoundingMode m, int s, int len) {
+    assert(m != 2 && m != 3, "invalid mode");
+    return uimm(m, 4) << (len-s-4);
+  }
+
+  //--------------------------------------------
+  // instruction field getter methods
+  //--------------------------------------------
+
+  static int get_imm32(address a, int instruction_number) {
+    int imm;
+    int *p =((int *)(a + 2 + 6 * instruction_number));
+    imm = *p;
+    return imm;
+  }
+
+  static short get_imm16(address a, int instruction_number) {
+    short imm;
+    short *p =((short *)a) + 2 * instruction_number + 1;
+    imm = *p;
+    return imm;
+  }
+
+
+  //--------------------------------------------
+  // instruction field setter methods
+  //--------------------------------------------
+
+  static void set_imm32(address a, int64_t s) {
+    assert(Immediate::is_simm32(s) || Immediate::is_uimm32(s), "to big");
+    int* p = (int *) (a + 2);
+    *p = s;
+  }
+
+  static void set_imm16(int* instr, int64_t s) {
+    assert(Immediate::is_simm16(s) || Immediate::is_uimm16(s), "to big");
+    short* p = ((short *)instr) + 1;
+    *p = s;
+  }
+
+ public:
+
+  static unsigned int align(unsigned int x, unsigned int a) { return ((x + (a - 1)) & ~(a - 1)); }
+  static bool    is_aligned(unsigned int x, unsigned int a) { return (0 == x % a); }
+
+  inline void emit_16(int x);
+  inline void emit_32(int x);
+  inline void emit_48(long x);
+
+  // Compare and control flow instructions
+  // =====================================
+
+  // See also commodity routines compare64_and_branch(), compare32_and_branch().
+
+  // compare instructions
+  // compare register
+  inline void z_cr(  Register r1, Register r2);                          // compare (r1, r2)        ; int32
+  inline void z_cgr( Register r1, Register r2);                          // compare (r1, r2)        ; int64
+  inline void z_cgfr(Register r1, Register r2);                          // compare (r1, r2)        ; int64 <--> int32
+   // compare immediate
+  inline void z_chi( Register r1, int64_t i2);                           // compare (r1, i2_imm16)  ; int32
+  inline void z_cfi( Register r1, int64_t i2);                           // compare (r1, i2_imm32)  ; int32
+  inline void z_cghi(Register r1, int64_t i2);                           // compare (r1, i2_imm16)  ; int64
+  inline void z_cgfi(Register r1, int64_t i2);                           // compare (r1, i2_imm32)  ; int64
+   // compare memory
+  inline void z_ch(  Register r1, const Address &a);                     // compare (r1, *(a))               ; int32 <--> int16
+  inline void z_ch(  Register r1, int64_t d2, Register x2, Register b2); // compare (r1, *(d2_uimm12+x2+b2)) ; int32 <--> int16
+  inline void z_c(   Register r1, const Address &a);                     // compare (r1, *(a))               ; int32
+  inline void z_c(   Register r1, int64_t d2, Register x2, Register b2); // compare (r1, *(d2_uimm12+x2+b2)) ; int32
+  inline void z_cy(  Register r1, int64_t d2, Register x2, Register b2); // compare (r1, *(d2_uimm20+x2+b2)) ; int32
+  inline void z_cy(  Register r1, int64_t d2, Register b2);              // compare (r1, *(d2_uimm20+x2+b2)) ; int32
+  inline void z_cy(  Register r1, const Address& a);                     // compare (r1, *(a))               ; int32
+   //inline void z_cgf(Register r1,const Address &a);                    // compare (r1, *(a))               ; int64 <--> int32
+   //inline void z_cgf(Register r1,int64_t d2, Register x2, Register b2);// compare (r1, *(d2_uimm12+x2+b2)) ; int64 <--> int32
+  inline void z_cg(  Register r1, const Address &a);                     // compare (r1, *(a))               ; int64
+  inline void z_cg(  Register r1, int64_t d2, Register x2, Register b2); // compare (r1, *(d2_imm20+x2+b2))  ; int64
+
+   // compare logical instructions
+   // compare register
+  inline void z_clr(  Register r1, Register r2);                         // compare (r1, r2)                 ; uint32
+  inline void z_clgr( Register r1, Register r2);                         // compare (r1, r2)                 ; uint64
+   // compare immediate
+  inline void z_clfi( Register r1, int64_t i2);                          // compare (r1, i2_uimm32)          ; uint32
+  inline void z_clgfi(Register r1, int64_t i2);                          // compare (r1, i2_uimm32)          ; uint64
+  inline void z_cl(   Register r1, const Address &a);                    // compare (r1, *(a)                ; uint32
+  inline void z_cl(   Register r1, int64_t d2, Register x2, Register b2);// compare (r1, *(d2_uimm12+x2+b2)  ; uint32
+  inline void z_cly(  Register r1, int64_t d2, Register x2, Register b2);// compare (r1, *(d2_uimm20+x2+b2)) ; uint32
+  inline void z_cly(  Register r1, int64_t d2, Register b2);             // compare (r1, *(d2_uimm20+x2+b2)) ; uint32
+  inline void z_cly(  Register r1, const Address& a);                    // compare (r1, *(a))               ; uint32
+  inline void z_clg(  Register r1, const Address &a);                    // compare (r1, *(a)                ; uint64
+  inline void z_clg(  Register r1, int64_t d2, Register x2, Register b2);// compare (r1, *(d2_imm20+x2+b2)   ; uint64
+
+  // test under mask
+  inline void z_tmll(Register r1, int64_t i2);           // test under mask, see docu
+  inline void z_tmlh(Register r1, int64_t i2);           // test under mask, see docu
+  inline void z_tmhl(Register r1, int64_t i2);           // test under mask, see docu
+  inline void z_tmhh(Register r1, int64_t i2);           // test under mask, see docu
+
+  // branch instructions
+  inline void z_bc(  branch_condition m1, int64_t d2, Register x2, Register b2);// branch  m1 ? pc = (d2_uimm12+x2+b2)
+  inline void z_bcr( branch_condition m1, Register r2);                         // branch (m1 && r2!=R0) ? pc = r2
+  inline void z_brc( branch_condition i1, int64_t i2);                          // branch  i1 ? pc = pc + i2_imm16
+  inline void z_brc( branch_condition i1, address a);                           // branch  i1 ? pc = a
+  inline void z_brc( branch_condition i1, Label& L);                            // branch  i1 ? pc = Label
+  //inline void z_brcl(branch_condition i1, int64_t i2);                        // branch  i1 ? pc = pc + i2_imm32
+  inline void z_brcl(branch_condition i1, address a);                           // branch  i1 ? pc = a
+  inline void z_brcl(branch_condition i1, Label& L);                            // branch  i1 ? pc = Label
+  inline void z_bctgr(Register r1, Register r2);         // branch on count r1 -= 1; (r1!=0) ? pc = r2  ; r1 is int64
+
+  // branch unconditional / always
+  inline void z_br(Register r2);                         // branch to r2, nop if r2 == Z_R0
+
+
+  // See also commodity routines compare64_and_branch(), compare32_and_branch().
+  // signed comparison and branch
+  inline void z_crb( Register r1, Register r2, branch_condition m3, int64_t d4, Register b4); // (r1 m3 r2) ? goto b4+d4      ; int32  -- z10
+  inline void z_cgrb(Register r1, Register r2, branch_condition m3, int64_t d4, Register b4); // (r1 m3 r2) ? goto b4+d4      ; int64  -- z10
+  inline void z_crj( Register r1, Register r2, branch_condition m3, Label& L);                // (r1 m3 r2) ? goto L          ; int32  -- z10
+  inline void z_crj( Register r1, Register r2, branch_condition m3, address a4);              // (r1 m3 r2) ? goto (pc+a4<<1) ; int32  -- z10
+  inline void z_cgrj(Register r1, Register r2, branch_condition m3, Label& L);                // (r1 m3 r2) ? goto L          ; int64  -- z10
+  inline void z_cgrj(Register r1, Register r2, branch_condition m3, address a4);              // (r1 m3 r2) ? goto (pc+a4<<1) ; int64  -- z10
+  inline void z_cib( Register r1, int64_t i2, branch_condition m3, int64_t d4, Register b4);  // (r1 m3 i2_imm8) ? goto b4+d4      ; int32  -- z10
+  inline void z_cgib(Register r1, int64_t i2, branch_condition m3, int64_t d4, Register b4);  // (r1 m3 i2_imm8) ? goto b4+d4      ; int64  -- z10
+  inline void z_cij( Register r1, int64_t i2, branch_condition m3, Label& L);                 // (r1 m3 i2_imm8) ? goto L          ; int32  -- z10
+  inline void z_cij( Register r1, int64_t i2, branch_condition m3, address a4);               // (r1 m3 i2_imm8) ? goto (pc+a4<<1) ; int32  -- z10
+  inline void z_cgij(Register r1, int64_t i2, branch_condition m3, Label& L);                 // (r1 m3 i2_imm8) ? goto L          ; int64  -- z10
+  inline void z_cgij(Register r1, int64_t i2, branch_condition m3, address a4);               // (r1 m3 i2_imm8) ? goto (pc+a4<<1) ; int64  -- z10
+  // unsigned comparison and branch
+  inline void z_clrb( Register r1, Register r2, branch_condition m3, int64_t d4, Register b4);// (r1 m3 r2) ? goto b4+d4      ; uint32  -- z10
+  inline void z_clgrb(Register r1, Register r2, branch_condition m3, int64_t d4, Register b4);// (r1 m3 r2) ? goto b4+d4      ; uint64  -- z10
+  inline void z_clrj( Register r1, Register r2, branch_condition m3, Label& L);               // (r1 m3 r2) ? goto L          ; uint32  -- z10
+  inline void z_clrj( Register r1, Register r2, branch_condition m3, address a4);             // (r1 m3 r2) ? goto (pc+a4<<1) ; uint32  -- z10
+  inline void z_clgrj(Register r1, Register r2, branch_condition m3, Label& L);               // (r1 m3 r2) ? goto L          ; uint64  -- z10
+  inline void z_clgrj(Register r1, Register r2, branch_condition m3, address a4);             // (r1 m3 r2) ? goto (pc+a4<<1) ; uint64  -- z10
+  inline void z_clib( Register r1, int64_t i2, branch_condition m3, int64_t d4, Register b4); // (r1 m3 i2_uimm8) ? goto b4+d4      ; uint32  -- z10
+  inline void z_clgib(Register r1, int64_t i2, branch_condition m3, int64_t d4, Register b4); // (r1 m3 i2_uimm8) ? goto b4+d4      ; uint64  -- z10
+  inline void z_clij( Register r1, int64_t i2, branch_condition m3, Label& L);                // (r1 m3 i2_uimm8) ? goto L          ; uint32  -- z10
+  inline void z_clij( Register r1, int64_t i2, branch_condition m3, address a4);              // (r1 m3 i2_uimm8) ? goto (pc+a4<<1) ; uint32  -- z10
+  inline void z_clgij(Register r1, int64_t i2, branch_condition m3, Label& L);                // (r1 m3 i2_uimm8) ? goto L          ; uint64  -- z10
+  inline void z_clgij(Register r1, int64_t i2, branch_condition m3, address a4);              // (r1 m3 i2_uimm8) ? goto (pc+a4<<1) ; uint64  -- z10
+
+  // Compare and trap instructions.
+  // signed comparison
+  inline void z_crt(Register r1,  Register r2, int64_t m3);  // (r1 m3 r2)        ? trap ; int32  -- z10
+  inline void z_cgrt(Register r1, Register r2, int64_t m3);  // (r1 m3 r2)        ? trap ; int64  -- z10
+  inline void z_cit(Register r1,  int64_t i2, int64_t m3);   // (r1 m3 i2_imm16)  ? trap ; int32  -- z10
+  inline void z_cgit(Register r1, int64_t i2, int64_t m3);   // (r1 m3 i2_imm16)  ? trap ; int64  -- z10
+  // unsigned comparison
+  inline void z_clrt(Register r1,  Register r2, int64_t m3); // (r1 m3 r2)        ? trap ; uint32 -- z10
+  inline void z_clgrt(Register r1, Register r2, int64_t m3); // (r1 m3 r2)        ? trap ; uint64 -- z10
+  inline void z_clfit(Register r1,  int64_t i2, int64_t m3); // (r1 m3 i2_uimm16) ? trap ; uint32 -- z10
+  inline void z_clgit(Register r1, int64_t i2, int64_t m3);  // (r1 m3 i2_uimm16) ? trap ; uint64 -- z10
+
+  inline void z_illtrap();
+  inline void z_illtrap(int id);
+  inline void z_illtrap_eyecatcher(unsigned short xpattern, unsigned short pattern);
+
+
+  // load address, add for addresses
+  // ===============================
+
+  // The versions without suffix z assert that the base reg is != Z_R0.
+  // Z_R0 is interpreted as constant '0'. The variants with Address operand
+  // check this automatically, so no two versions are needed.
+  inline void z_layz(Register r1, int64_t d2, Register x2, Register b2); // Special version. Allows Z_R0 as base reg.
+  inline void z_lay(Register r1, const Address &a);                      // r1 = a
+  inline void z_lay(Register r1, int64_t d2, Register x2, Register b2);  // r1 = d2_imm20+x2+b2
+  inline void z_laz(Register r1, int64_t d2, Register x2, Register b2);  // Special version. Allows Z_R0 as base reg.
+  inline void z_la(Register r1, const Address &a);                       // r1 = a                ; unsigned immediate!
+  inline void z_la(Register r1, int64_t d2, Register x2, Register b2);   // r1 = d2_uimm12+x2+b2  ; unsigned immediate!
+  inline void z_larl(Register r1, int64_t i2);                           // r1 = pc + i2_imm32<<1;
+  inline void z_larl(Register r1, address a2);                           // r1 = pc + i2_imm32<<1;
+
+  // Load instructions for integers
+  // ==============================
+
+  // Address as base + index + offset
+  inline void z_lb( Register r1, const Address &a);                     // load r1 = *(a)              ; int32 <- int8
+  inline void z_lb( Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm20+x2+b2) ; int32 <- int8
+  inline void z_lh( Register r1, const Address &a);                     // load r1 = *(a)              ; int32 <- int16
+  inline void z_lh( Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_uimm12+x2+b2); int32 <- int16
+  inline void z_lhy(Register r1, const Address &a);                     // load r1 = *(a)              ; int32 <- int16
+  inline void z_lhy(Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm20+x2+b2) ; int32 <- int16
+  inline void z_l(  Register r1, const Address& a);                     // load r1 = *(a)              ; int32
+  inline void z_l(  Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_uimm12+x2+b2); int32
+  inline void z_ly( Register r1, const Address& a);                     // load r1 = *(a)              ; int32
+  inline void z_ly( Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm20+x2+b2) ; int32
+
+  inline void z_lgb(Register r1, const Address &a);                     // load r1 = *(a)              ; int64 <- int8
+  inline void z_lgb(Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm20+x2+b2) ; int64 <- int8
+  inline void z_lgh(Register r1, const Address &a);                     // load r1 = *(a)              ; int64 <- int16
+  inline void z_lgh(Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm12+x2+b2) ; int64 <- int16
+  inline void z_lgf(Register r1, const Address &a);                     // load r1 = *(a)              ; int64 <- int32
+  inline void z_lgf(Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm20+x2+b2) ; int64 <- int32
+  inline void z_lg( Register r1, const Address& a);                     // load r1 = *(a)              ; int64 <- int64
+  inline void z_lg( Register r1, int64_t d2, Register x2, Register b2); // load r1 = *(d2_imm20+x2+b2) ; int64 <- int64
+
+  // load and test
+  inline void z_lt(  Register r1, const Address &a);                    // load and test r1 = *(a)              ; int32
+  inline void z_lt(  Register r1, int64_t d2, Register x2, Register b2);// load and test r1 = *(d2_imm20+x2+b2) ; int32
+  inline void z_ltg( Register r1, const Address &a);                    // load and test r1 = *(a)              ; int64
+  inline void z_ltg( Register r1, int64_t d2, Register x2, Register b2);// load and test r1 = *(d2_imm20+x2+b2) ; int64
+  inline void z_ltgf(Register r1, const Address &a);                    // load and test r1 = *(a)              ; int64 <- int32
+  inline void z_ltgf(Register r1, int64_t d2, Register x2, Register b2);// load and test r1 = *(d2_imm20+x2+b2) ; int64 <- int32
+
+  // load unsigned integer - zero extended
+  inline void z_llc( Register r1, const Address& a);                    // load r1 = *(a)              ; uint32 <- uint8
+  inline void z_llc( Register r1, int64_t d2, Register x2, Register b2);// load r1 = *(d2_imm20+x2+b2) ; uint32 <- uint8
+  inline void z_llh( Register r1, const Address& a);                    // load r1 = *(a)              ; uint32 <- uint16
+  inline void z_llh( Register r1, int64_t d2, Register x2, Register b2);// load r1 = *(d2_imm20+x2+b2) ; uint32 <- uint16
+  inline void z_llgc(Register r1, const Address& a);                    // load r1 = *(a)              ; uint64 <- uint8
+  inline void z_llgc(Register r1, int64_t d2, Register x2, Register b2);// load r1 = *(d2_imm20+x2+b2) ; uint64 <- uint8
+  inline void z_llgc( Register r1, int64_t d2, Register b2);            // load r1 = *(d2_imm20+b2)    ; uint64 <- uint8
+  inline void z_llgh(Register r1, const Address& a);                    // load r1 = *(a)              ; uint64 <- uint16
+  inline void z_llgh(Register r1, int64_t d2, Register x2, Register b2);// load r1 = *(d2_imm20+x2+b2) ; uint64 <- uint16
+  inline void z_llgf(Register r1, const Address& a);                    // load r1 = *(a)              ; uint64 <- uint32
+  inline void z_llgf(Register r1, int64_t d2, Register x2, Register b2);// load r1 = *(d2_imm20+x2+b2) ; uint64 <- uint32
+
+  // pc relative addressing
+  inline void z_lhrl( Register r1, int64_t i2);   // load r1 = *(pc + i2_imm32<<1) ; int32 <- int16    -- z10
+  inline void z_lrl(  Register r1, int64_t i2);   // load r1 = *(pc + i2_imm32<<1) ; int32             -- z10
+  inline void z_lghrl(Register r1, int64_t i2);   // load r1 = *(pc + i2_imm32<<1) ; int64 <- int16    -- z10
+  inline void z_lgfrl(Register r1, int64_t i2);   // load r1 = *(pc + i2_imm32<<1) ; int64 <- int32    -- z10
+  inline void z_lgrl( Register r1, int64_t i2);   // load r1 = *(pc + i2_imm32<<1) ; int64             -- z10
+
+  inline void z_llhrl( Register r1, int64_t i2);  // load r1 = *(pc + i2_imm32<<1) ; uint32 <- uint16  -- z10
+  inline void z_llghrl(Register r1, int64_t i2);  // load r1 = *(pc + i2_imm32<<1) ; uint64 <- uint16  -- z10
+  inline void z_llgfrl(Register r1, int64_t i2);  // load r1 = *(pc + i2_imm32<<1) ; uint64 <- uint32  -- z10
+
+  // Store instructions for integers
+  // ===============================
+
+  // Address as base + index + offset
+  inline void z_stc( Register r1, const Address &d);                     // store *(a)               = r1  ; int8
+  inline void z_stc( Register r1, int64_t d2, Register x2, Register b2); // store *(d2_uimm12+x2+b2) = r1  ; int8
+  inline void z_stcy(Register r1, const Address &d);                     // store *(a)               = r1  ; int8
+  inline void z_stcy(Register r1, int64_t d2, Register x2, Register b2); // store *(d2_imm20+x2+b2)  = r1  ; int8
+  inline void z_sth( Register r1, const Address &d);                     // store *(a)               = r1  ; int16
+  inline void z_sth( Register r1, int64_t d2, Register x2, Register b2); // store *(d2_uimm12+x2+b2) = r1  ; int16
+  inline void z_sthy(Register r1, const Address &d);                     // store *(a)               = r1  ; int16
+  inline void z_sthy(Register r1, int64_t d2, Register x2, Register b2); // store *(d2_imm20+x2+b2)  = r1  ; int16
+  inline void z_st(  Register r1, const Address &d);                     // store *(a)               = r1  ; int32
+  inline void z_st(  Register r1, int64_t d2, Register x2, Register b2); // store *(d2_uimm12+x2+b2) = r1  ; int32
+  inline void z_sty( Register r1, const Address &d);                     // store *(a)               = r1  ; int32
+  inline void z_sty( Register r1, int64_t d2, Register x2, Register b2); // store *(d2_imm20+x2+b2)  = r1  ; int32
+  inline void z_stg( Register r1, const Address &d);                     // store *(a)               = r1  ; int64
+  inline void z_stg( Register r1, int64_t d2, Register x2, Register b2); // store *(d2_uimm12+x2+b2) = r1  ; int64
+
+  inline void z_stcm( Register r1, int64_t m3, int64_t d2, Register b2); // store character under mask
+  inline void z_stcmy(Register r1, int64_t m3, int64_t d2, Register b2); // store character under mask
+  inline void z_stcmh(Register r1, int64_t m3, int64_t d2, Register b2); // store character under mask
+
+  // pc relative addressing
+  inline void z_sthrl(Register r1, int64_t i2);   // store *(pc + i2_imm32<<1) = r1 ; int16  -- z10
+  inline void z_strl( Register r1, int64_t i2);   // store *(pc + i2_imm32<<1) = r1 ; int32  -- z10
+  inline void z_stgrl(Register r1, int64_t i2);   // store *(pc + i2_imm32<<1) = r1 ; int64  -- z10
+
+
+  // Load and store immediates
+  // =========================
+
+  // load immediate
+  inline void z_lhi( Register r1, int64_t i2);                  // r1 = i2_imm16    ; int32 <- int16
+  inline void z_lghi(Register r1, int64_t i2);                  // r1 = i2_imm16    ; int64 <- int16
+  inline void z_lgfi(Register r1, int64_t i2);                  // r1 = i2_imm32    ; int64 <- int32
+
+  inline void z_llihf(Register r1, int64_t i2);                 // r1 = i2_imm32    ; uint64 <- (uint32<<32)
+  inline void z_llilf(Register r1, int64_t i2);                 // r1 = i2_imm32    ; uint64 <- uint32
+  inline void z_llihh(Register r1, int64_t i2);                 // r1 = i2_imm16    ; uint64 <- (uint16<<48)
+  inline void z_llihl(Register r1, int64_t i2);                 // r1 = i2_imm16    ; uint64 <- (uint16<<32)
+  inline void z_llilh(Register r1, int64_t i2);                 // r1 = i2_imm16    ; uint64 <- (uint16<<16)
+  inline void z_llill(Register r1, int64_t i2);                 // r1 = i2_imm16    ; uint64 <- uint16
+
+  // insert immediate
+  inline void z_ic(  Register r1, int64_t d2, Register x2, Register b2); // insert character
+  inline void z_icy( Register r1, int64_t d2, Register x2, Register b2); // insert character
+  inline void z_icm( Register r1, int64_t m3, int64_t d2, Register b2);  // insert character under mask
+  inline void z_icmy(Register r1, int64_t m3, int64_t d2, Register b2);  // insert character under mask
+  inline void z_icmh(Register r1, int64_t m3, int64_t d2, Register b2);  // insert character under mask
+
+  inline void z_iihh(Register r1, int64_t i2);                  // insert immediate  r1[ 0-15] = i2_imm16
+  inline void z_iihl(Register r1, int64_t i2);                  // insert immediate  r1[16-31] = i2_imm16
+  inline void z_iilh(Register r1, int64_t i2);                  // insert immediate  r1[32-47] = i2_imm16
+  inline void z_iill(Register r1, int64_t i2);                  // insert immediate  r1[48-63] = i2_imm16
+  inline void z_iihf(Register r1, int64_t i2);                  // insert immediate  r1[32-63] = i2_imm32
+  inline void z_iilf(Register r1, int64_t i2);                  // insert immediate  r1[ 0-31] = i2_imm32
+
+  // store immediate
+  inline void z_mvhhi(const Address &d, int64_t i2);            // store *(d)           = i2_imm16 ; int16
+  inline void z_mvhhi(int64_t d1, Register b1, int64_t i2);     // store *(d1_imm12+b1) = i2_imm16 ; int16
+  inline void z_mvhi( const Address &d, int64_t i2);            // store *(d)           = i2_imm16 ; int32
+  inline void z_mvhi( int64_t d1, Register b1, int64_t i2);     // store *(d1_imm12+b1) = i2_imm16 ; int32
+  inline void z_mvghi(const Address &d, int64_t i2);            // store *(d)           = i2_imm16 ; int64
+  inline void z_mvghi(int64_t d1, Register b1, int64_t i2);     // store *(d1_imm12+b1) = i2_imm16 ; int64
+
+  // Move and Convert instructions
+  // =============================
+
+  // move, sign extend
+  inline void z_lbr(Register r1, Register r2);             // move r1 = r2 ; int32  <- int8
+  inline void z_lhr( Register r1, Register r2);            // move r1 = r2 ; int32  <- int16
+  inline void z_lr(Register r1, Register r2);              // move r1 = r2 ; int32, no sign extension
+  inline void z_lgbr(Register r1, Register r2);            // move r1 = r2 ; int64  <- int8
+  inline void z_lghr(Register r1, Register r2);            // move r1 = r2 ; int64  <- int16
+  inline void z_lgfr(Register r1, Register r2);            // move r1 = r2 ; int64  <- int32
+  inline void z_lgr(Register r1, Register r2);             // move r1 = r2 ; int64
+  // move, zero extend
+  inline void z_llhr( Register r1, Register r2);           // move r1 = r2 ; uint32 <- uint16
+  inline void z_llgcr(Register r1, Register r2);           // move r1 = r2 ; uint64 <- uint8
+  inline void z_llghr(Register r1, Register r2);           // move r1 = r2 ; uint64 <- uint16
+  inline void z_llgfr(Register r1, Register r2);           // move r1 = r2 ; uint64 <- uint32
+
+  // move and test register
+  inline void z_ltr(Register r1, Register r2);             // load/move and test r1 = r2; int32
+  inline void z_ltgr(Register r1, Register r2);            // load/move and test r1 = r2; int64
+  inline void z_ltgfr(Register r1, Register r2);           // load/move and test r1 = r2; int64 <-- int32
+
+  // move and byte-reverse
+  inline void z_lrvr( Register r1, Register r2);           // move and reverse byte order r1 = r2; int32
+  inline void z_lrvgr(Register r1, Register r2);           // move and reverse byte order r1 = r2; int64
+
+
+  // Arithmetic instructions (Integer only)
+  // ======================================
+  // For float arithmetic instructions scroll further down
+  // Add logical differs in the condition codes set!
+
+  // add registers
+  inline void z_ar(   Register r1, Register r2);                      // add         r1 = r1 + r2  ; int32
+  inline void z_agr(  Register r1, Register r2);                      // add         r1 = r1 + r2  ; int64
+  inline void z_agfr( Register r1, Register r2);                      // add         r1 = r1 + r2  ; int64 <- int32
+  inline void z_ark(  Register r1, Register r2, Register r3);         // add         r1 = r2 + r3  ; int32
+  inline void z_agrk( Register r1, Register r2, Register r3);         // add         r1 = r2 + r3  ; int64
+
+  inline void z_alr(  Register r1, Register r2);                      // add logical r1 = r1 + r2  ; int32
+  inline void z_algr( Register r1, Register r2);                      // add logical r1 = r1 + r2  ; int64
+  inline void z_algfr(Register r1, Register r2);                      // add logical r1 = r1 + r2  ; int64 <- int32
+  inline void z_alrk( Register r1, Register r2, Register r3);         // add logical r1 = r2 + r3  ; int32
+  inline void z_algrk(Register r1, Register r2, Register r3);         // add logical r1 = r2 + r3  ; int64
+  inline void z_alcgr(Register r1, Register r2);                      // add logical with carry r1 = r1 + r2 + c  ; int64
+
+  // add immediate
+  inline void z_ahi(  Register r1, int64_t i2);                       // add         r1 = r1 + i2_imm16 ; int32
+  inline void z_afi(  Register r1, int64_t i2);                       // add         r1 = r1 + i2_imm32 ; int32
+  inline void z_alfi( Register r1, int64_t i2);                       // add         r1 = r1 + i2_imm32 ; int32
+  inline void z_aghi( Register r1, int64_t i2);                       // add logical r1 = r1 + i2_imm16 ; int64
+  inline void z_agfi( Register r1, int64_t i2);                       // add         r1 = r1 + i2_imm32 ; int64
+  inline void z_algfi(Register r1, int64_t i2);                       // add logical r1 = r1 + i2_imm32 ; int64
+  inline void z_ahik( Register r1, Register r3, int64_t i2);          // add         r1 = r3 + i2_imm16 ; int32
+  inline void z_aghik(Register r1, Register r3, int64_t i2);          // add         r1 = r3 + i2_imm16 ; int64
+  inline void z_aih(  Register r1, int64_t i2);                       // add         r1 = r1 + i2_imm32 ; int32 (HiWord)
+
+  // add memory
+  inline void z_a( Register r1, int64_t d2, Register x2, Register b2);  // add r1 = r1 + *(d2_uimm12+s2+b2) ; int32
+  inline void z_ay(  Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_imm20+s2+b2)  ; int32
+  inline void z_ag(  Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_imm20+s2+b2)  ; int64
+  inline void z_agf( Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_imm20+x2+b2)  ; int64 <- int32
+  inline void z_al(  Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_uimm12+x2+b2) ; int32
+  inline void z_aly( Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_imm20+x2+b2)  ; int32
+  inline void z_alg( Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_imm20+x2+b2)  ; int64
+  inline void z_algf(Register r1, int64_t d2, Register x2, Register b2);// add r1 = r1 + *(d2_imm20+x2+b2)  ; int64 <- int32
+  inline void z_a(   Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int32
+  inline void z_ay(  Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int32
+  inline void z_al(  Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int32
+  inline void z_aly( Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int32
+  inline void z_ag(  Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int64
+  inline void z_agf( Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int64 <- int32
+  inline void z_alg( Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int64
+  inline void z_algf(Register r1, const Address& a);                  // add r1 = r1 + *(a)               ; int64 <- int32
+
+
+  inline void z_alhsik( Register r1, Register r3, int64_t i2);    // add logical r1 = r3 + i2_imm16   ; int32
+  inline void z_alghsik(Register r1, Register r3, int64_t i2);    // add logical r1 = r3 + i2_imm16   ; int64
+
+  inline void z_asi(  int64_t d1, Register b1, int64_t i2);       // add           *(d1_imm20+b1) += i2_imm8 ; int32   -- z10
+  inline void z_agsi( int64_t d1, Register b1, int64_t i2);       // add           *(d1_imm20+b1) += i2_imm8 ; int64   -- z10
+  inline void z_alsi( int64_t d1, Register b1, int64_t i2);       // add logical   *(d1_imm20+b1) += i2_imm8 ; uint32  -- z10
+  inline void z_algsi(int64_t d1, Register b1, int64_t i2);       // add logical   *(d1_imm20+b1) += i2_imm8 ; uint64  -- z10
+  inline void z_asi(  const Address& d, int64_t i2);              // add           *(d) += i2_imm8           ; int32   -- z10
+  inline void z_agsi( const Address& d, int64_t i2);              // add           *(d) += i2_imm8           ; int64   -- z10
+  inline void z_alsi( const Address& d, int64_t i2);              // add logical   *(d) += i2_imm8           ; uint32  -- z10
+  inline void z_algsi(const Address& d, int64_t i2);              // add logical   *(d) += i2_imm8           ; uint64  -- z10
+
+  // negate
+  inline void z_lcr(  Register r1, Register r2 = noreg);              // neg r1 = -r2   ; int32
+  inline void z_lcgr( Register r1, Register r2 = noreg);              // neg r1 = -r2   ; int64
+  inline void z_lcgfr(Register r1, Register r2);                      // neg r1 = -r2   ; int64 <- int32
+  inline void z_lnr(  Register r1, Register r2 = noreg);              // neg r1 = -|r2| ; int32
+  inline void z_lngr( Register r1, Register r2 = noreg);              // neg r1 = -|r2| ; int64
+  inline void z_lngfr(Register r1, Register r2);                      // neg r1 = -|r2| ; int64 <- int32
+
+  // subtract intstructions
+  // sub registers
+  inline void z_sr(   Register r1, Register r2);                      // sub         r1 = r1 - r2                ; int32
+  inline void z_sgr(  Register r1, Register r2);                      // sub         r1 = r1 - r2                ; int64
+  inline void z_sgfr( Register r1, Register r2);                      // sub         r1 = r1 - r2                ; int64 <- int32
+  inline void z_srk(  Register r1, Register r2, Register r3);         // sub         r1 = r2 - r3                ; int32
+  inline void z_sgrk( Register r1, Register r2, Register r3);         // sub         r1 = r2 - r3                ; int64
+
+  inline void z_slr(  Register r1, Register r2);                      // sub logical r1 = r1 - r2                ; int32
+  inline void z_slgr( Register r1, Register r2);                      // sub logical r1 = r1 - r2                ; int64
+  inline void z_slgfr(Register r1, Register r2);                      // sub logical r1 = r1 - r2                ; int64 <- int32
+  inline void z_slrk( Register r1, Register r2, Register r3);         // sub logical r1 = r2 - r3                ; int32
+  inline void z_slgrk(Register r1, Register r2, Register r3);         // sub logical r1 = r2 - r3                ; int64
+  inline void z_slfi( Register r1, int64_t i2);                       // sub logical r1 = r1 - i2_uimm32         ; int32
+  inline void z_slgfi(Register r1, int64_t i2);                       // add logical r1 = r1 - i2_uimm32         ; int64
+
+  // sub memory
+  inline void z_s(   Register r1, int64_t d2, Register x2, Register b2);  // sub         r1 = r1 - *(d2_imm12+x2+b2) ; int32
+  inline void z_sy(  Register r1, int64_t d2, Register x2, Register b2);  // sub         r1 = r1 + *(d2_imm20+s2+b2) ; int32
+  inline void z_sg(  Register r1, int64_t d2, Register x2, Register b2);  // sub         r1 = r1 - *(d2_imm12+x2+b2) ; int64
+  inline void z_sgf( Register r1, int64_t d2, Register x2, Register b2);  // sub         r1 = r1 - *(d2_imm12+x2+b2) ; int64 - int32
+  inline void z_slg( Register r1, int64_t d2, Register x2, Register b2);  // sub logical r1 = r1 - *(d2_imm20+x2+b2) ; uint64
+  inline void z_slgf(Register r1, int64_t d2, Register x2, Register b2);  // sub logical r1 = r1 - *(d2_imm20+x2+b2) ; uint64 - uint32
+  inline void z_s(   Register r1, const Address& a);                      // sub         r1 = r1 - *(a)              ; int32
+  inline void z_sy(  Register r1, const Address& a);                      // sub         r1 = r1 - *(a)              ; int32
+  inline void z_sg(  Register r1, const Address& a);                      // sub         r1 = r1 - *(a)              ; int64
+  inline void z_sgf( Register r1, const Address& a);                      // sub         r1 = r1 - *(a)              ; int64 - int32
+  inline void z_slg( Register r1, const Address& a);                      // sub         r1 = r1 - *(a)              ; uint64
+  inline void z_slgf(Register r1, const Address& a);                      // sub         r1 = r1 - *(a)              ; uint64 - uint32
+
+  inline void z_sh(  Register r1, int64_t d2, Register x2, Register b2);  // sub         r1 = r1 - *(d2_imm12+x2+b2) ; int32 - int16
+  inline void z_shy( Register r1, int64_t d2, Register x2, Register b2);  // sub         r1 = r1 - *(d2_imm20+x2+b2) ; int32 - int16
+  inline void z_sh(  Register r1, const Address &a);                      // sub         r1 = r1 - *(d2_imm12+x2+b2) ; int32 - int16
+  inline void z_shy( Register r1, const Address &a);                      // sub         r1 = r1 - *(d2_imm20+x2+b2) ; int32 - int16
+
+  // Multiplication instructions
+  // mul registers
+  inline void z_msr(  Register r1, Register r2);                          // mul r1 = r1 * r2          ; int32
+  inline void z_msgr( Register r1, Register r2);                          // mul r1 = r1 * r2          ; int64
+  inline void z_msgfr(Register r1, Register r2);                          // mul r1 = r1 * r2          ; int64 <- int32
+  inline void z_mlr(  Register r1, Register r2);                          // mul r1 = r1 * r2          ; int32 unsigned
+  inline void z_mlgr( Register r1, Register r2);                          // mul r1 = r1 * r2          ; int64 unsigned
+  // mul register - memory
+  inline void z_mhy( Register r1, int64_t d2, Register x2, Register b2);  // mul r1 = r1 * *(d2+x2+b2)
+  inline void z_msy( Register r1, int64_t d2, Register x2, Register b2);  // mul r1 = r1 * *(d2+x2+b2)
+  inline void z_msg( Register r1, int64_t d2, Register x2, Register b2);  // mul r1 = r1 * *(d2+x2+b2)
+  inline void z_msgf(Register r1, int64_t d2, Register x2, Register b2);  // mul r1 = r1 * *(d2+x2+b2)
+  inline void z_ml(  Register r1, int64_t d2, Register x2, Register b2);  // mul r1 = r1 * *(d2+x2+b2)
+  inline void z_mlg( Register r1, int64_t d2, Register x2, Register b2);  // mul r1 = r1 * *(d2+x2+b2)
+  inline void z_mhy( Register r1, const Address& a);                      // mul r1 = r1 * *(a)
+  inline void z_msy( Register r1, const Address& a);                      // mul r1 = r1 * *(a)
+  inline void z_msg( Register r1, const Address& a);                      // mul r1 = r1 * *(a)
+  inline void z_msgf(Register r1, const Address& a);                      // mul r1 = r1 * *(a)
+  inline void z_ml(  Register r1, const Address& a);                      // mul r1 = r1 * *(a)
+  inline void z_mlg( Register r1, const Address& a);                      // mul r1 = r1 * *(a)
+
+  inline void z_msfi( Register r1, int64_t i2);   // mult r1 = r1 * i2_imm32;   int32  -- z10
+  inline void z_msgfi(Register r1, int64_t i2);   // mult r1 = r1 * i2_imm32;   int64  -- z10
+  inline void z_mhi(  Register r1, int64_t i2);   // mult r1 = r1 * i2_imm16;   int32
+  inline void z_mghi( Register r1, int64_t i2);   // mult r1 = r1 * i2_imm16;   int64
+
+  // Division instructions
+  inline void z_dsgr( Register r1, Register r2);      // div  r1 = r1 / r2               ; int64/int32 needs reg pair!
+  inline void z_dsgfr(Register r1, Register r2);      // div  r1 = r1 / r2               ; int64/int32 needs reg pair!
+
+
+  // Logic instructions
+  // ===================
+
+  // and
+  inline void z_n(   Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_ny(  Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_ng(  Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_n(   Register r1, const Address& a);
+  inline void z_ny(  Register r1, const Address& a);
+  inline void z_ng(  Register r1, const Address& a);
+
+  inline void z_nr(  Register r1, Register r2);               // and r1 = r1 & r2         ; int32
+  inline void z_ngr( Register r1, Register r2);               // and r1 = r1 & r2         ; int64
+  inline void z_nrk( Register r1, Register r2, Register r3);  // and r1 = r2 & r3         ; int32
+  inline void z_ngrk(Register r1, Register r2, Register r3);  // and r1 = r2 & r3         ; int64
+
+  inline void z_nihh(Register r1, int64_t i2);                // and r1 = r1 & i2_imm16   ; and only for bits  0-15
+  inline void z_nihl(Register r1, int64_t i2);                // and r1 = r1 & i2_imm16   ; and only for bits 16-31
+  inline void z_nilh(Register r1, int64_t i2);                // and r1 = r1 & i2_imm16   ; and only for bits 32-47
+  inline void z_nill(Register r1, int64_t i2);                // and r1 = r1 & i2_imm16   ; and only for bits 48-63
+  inline void z_nihf(Register r1, int64_t i2);                // and r1 = r1 & i2_imm32   ; and only for bits  0-31
+  inline void z_nilf(Register r1, int64_t i2);                // and r1 = r1 & i2_imm32   ; and only for bits 32-63  see also MacroAssembler::nilf.
+
+  // or
+  inline void z_o(   Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_oy(  Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_og(  Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_o(   Register r1, const Address& a);
+  inline void z_oy(  Register r1, const Address& a);
+  inline void z_og(  Register r1, const Address& a);
+
+  inline void z_or(  Register r1, Register r2);               // or r1 = r1 | r2; int32
+  inline void z_ogr( Register r1, Register r2);               // or r1 = r1 | r2; int64
+  inline void z_ork( Register r1, Register r2, Register r3);  // or r1 = r2 | r3         ; int32
+  inline void z_ogrk(Register r1, Register r2, Register r3);  // or r1 = r2 | r3         ; int64
+
+  inline void z_oihh(Register r1, int64_t i2);                // or r1 = r1 | i2_imm16   ; or only for bits  0-15
+  inline void z_oihl(Register r1, int64_t i2);                // or r1 = r1 | i2_imm16   ; or only for bits 16-31
+  inline void z_oilh(Register r1, int64_t i2);                // or r1 = r1 | i2_imm16   ; or only for bits 32-47
+  inline void z_oill(Register r1, int64_t i2);                // or r1 = r1 | i2_imm16   ; or only for bits 48-63
+  inline void z_oihf(Register r1, int64_t i2);                // or r1 = r1 | i2_imm32   ; or only for bits  0-31
+  inline void z_oilf(Register r1, int64_t i2);                // or r1 = r1 | i2_imm32   ; or only for bits 32-63
+
+  // xor
+  inline void z_x(   Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_xy(  Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_xg(  Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_x(   Register r1, const Address& a);
+  inline void z_xy(  Register r1, const Address& a);
+  inline void z_xg(  Register r1, const Address& a);
+
+  inline void z_xr(  Register r1, Register r2);               // xor r1 = r1 ^ r2         ; int32
+  inline void z_xgr( Register r1, Register r2);               // xor r1 = r1 ^ r2         ; int64
+  inline void z_xrk( Register r1, Register r2, Register r3);  // xor r1 = r2 ^ r3         ; int32
+  inline void z_xgrk(Register r1, Register r2, Register r3);  // xor r1 = r2 ^ r3         ; int64
+
+  inline void z_xihf(Register r1, int64_t i2);                // xor r1 = r1 ^ i2_imm32   ; or only for bits  0-31
+  inline void z_xilf(Register r1, int64_t i2);                // xor r1 = r1 ^ i2_imm32   ; or only for bits 32-63
+
+  // shift
+  inline void z_sla( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved!
+  inline void z_slag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, only 63 bits shifted, sign preserved!
+  inline void z_sra( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, sign extended
+  inline void z_srag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, sign extended
+  inline void z_sll( Register r1,              int64_t d2, Register b2=Z_R0); // shift left  r1 = r1 << ((d2+b2)&0x3f) ; int32, zeros added
+  inline void z_sllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left  r1 = r3 << ((d2+b2)&0x3f) ; int64, zeros added
+  inline void z_srl( Register r1,              int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, zero extended
+  inline void z_srlg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, zero extended
+
+  // rotate
+  inline void z_rll( Register r1, Register r3, int64_t d2, Register b2=Z_R0); // rot r1 = r3 << (d2+b2 & 0x3f) ; int32  -- z10
+  inline void z_rllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // rot r1 = r3 << (d2+b2 & 0x3f) ; int64  -- z10
+
+  // rotate the AND/XOR/OR/insert
+  inline void z_rnsbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only = false); // rotate then AND selected bits  -- z196
+  inline void z_rxsbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only = false); // rotate then XOR selected bits  -- z196
+  inline void z_rosbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only = false); // rotate then OR  selected bits  -- z196
+  inline void z_risbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool zero_rest = false); // rotate then INS selected bits  -- z196
+
+
+  // memory-immediate instructions (8-bit immediate)
+  // ===============================================
+
+  inline void z_cli( int64_t d1, Register b1, int64_t i2); // compare *(d1_imm12+b1) ^= i2_imm8           ; int8
+  inline void z_mvi( int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1)  = i2_imm8           ; int8
+  inline void z_tm(  int64_t d1, Register b1, int64_t i2); // test    *(d1_imm12+b1) against mask i2_imm8 ; int8
+  inline void z_ni(  int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1) &= i2_imm8           ; int8
+  inline void z_oi(  int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1) |= i2_imm8           ; int8
+  inline void z_xi(  int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1) ^= i2_imm8           ; int8
+  inline void z_cliy(int64_t d1, Register b1, int64_t i2); // compare *(d1_imm12+b1) ^= i2_imm8           ; int8
+  inline void z_mviy(int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1)  = i2_imm8           ; int8
+  inline void z_tmy( int64_t d1, Register b1, int64_t i2); // test    *(d1_imm12+b1) against mask i2_imm8 ; int8
+  inline void z_niy( int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1) &= i2_imm8           ; int8
+  inline void z_oiy( int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1) |= i2_imm8           ; int8
+  inline void z_xiy( int64_t d1, Register b1, int64_t i2); // store   *(d1_imm12+b1) ^= i2_imm8           ; int8
+  inline void z_cli( const Address& a, int64_t imm8);      // compare *(a)           ^= imm8              ; int8
+  inline void z_mvi( const Address& a, int64_t imm8);      // store   *(a)            = imm8              ; int8
+  inline void z_tm(  const Address& a, int64_t imm8);      // test    *(a)           against mask imm8    ; int8
+  inline void z_ni(  const Address& a, int64_t imm8);      // store   *(a)           &= imm8              ; int8
+  inline void z_oi(  const Address& a, int64_t imm8);      // store   *(a)           |= imm8              ; int8
+  inline void z_xi(  const Address& a, int64_t imm8);      // store   *(a)           ^= imm8              ; int8
+  inline void z_cliy(const Address& a, int64_t imm8);      // compare *(a)           ^= imm8              ; int8
+  inline void z_mviy(const Address& a, int64_t imm8);      // store   *(a)            = imm8              ; int8
+  inline void z_tmy( const Address& a, int64_t imm8);      // test    *(a)           against mask imm8    ; int8
+  inline void z_niy( const Address& a, int64_t imm8);      // store   *(a)           &= imm8              ; int8
+  inline void z_oiy( const Address& a, int64_t imm8);      // store   *(a)           |= imm8              ; int8
+  inline void z_xiy( const Address& a, int64_t imm8);      // store   *(a)           ^= imm8              ; int8
+
+
+  //------------------------------
+  // Interlocked-Update
+  //------------------------------
+  inline void z_laa(  Register r1, Register r3, int64_t d2, Register b2);   // load and add    int32, signed   -- z196
+  inline void z_laag( Register r1, Register r3, int64_t d2, Register b2);   // load and add    int64, signed   -- z196
+  inline void z_laal( Register r1, Register r3, int64_t d2, Register b2);   // load and add    int32, unsigned -- z196
+  inline void z_laalg(Register r1, Register r3, int64_t d2, Register b2);   // load and add    int64, unsigned -- z196
+  inline void z_lan(  Register r1, Register r3, int64_t d2, Register b2);   // load and and    int32           -- z196
+  inline void z_lang( Register r1, Register r3, int64_t d2, Register b2);   // load and and    int64           -- z196
+  inline void z_lax(  Register r1, Register r3, int64_t d2, Register b2);   // load and xor    int32           -- z196
+  inline void z_laxg( Register r1, Register r3, int64_t d2, Register b2);   // load and xor    int64           -- z196
+  inline void z_lao(  Register r1, Register r3, int64_t d2, Register b2);   // load and or     int32           -- z196
+  inline void z_laog( Register r1, Register r3, int64_t d2, Register b2);   // load and or     int64           -- z196
+
+  inline void z_laa(  Register r1, Register r3, const Address& a);          // load and add    int32, signed   -- z196
+  inline void z_laag( Register r1, Register r3, const Address& a);          // load and add    int64, signed   -- z196
+  inline void z_laal( Register r1, Register r3, const Address& a);          // load and add    int32, unsigned -- z196
+  inline void z_laalg(Register r1, Register r3, const Address& a);          // load and add    int64, unsigned -- z196
+  inline void z_lan(  Register r1, Register r3, const Address& a);          // load and and    int32           -- z196
+  inline void z_lang( Register r1, Register r3, const Address& a);          // load and and    int64           -- z196
+  inline void z_lax(  Register r1, Register r3, const Address& a);          // load and xor    int32           -- z196
+  inline void z_laxg( Register r1, Register r3, const Address& a);          // load and xor    int64           -- z196
+  inline void z_lao(  Register r1, Register r3, const Address& a);          // load and or     int32           -- z196
+  inline void z_laog( Register r1, Register r3, const Address& a);          // load and or     int64           -- z196
+
+  //--------------------------------
+  // Execution Prediction
+  //--------------------------------
+  inline void z_pfd(  int64_t m1, int64_t d2, Register x2, Register b2);  // prefetch
+  inline void z_pfd(  int64_t m1, Address a);
+  inline void z_pfdrl(int64_t m1, int64_t i2);                            // prefetch
+  inline void z_bpp(  int64_t m1, int64_t i2, int64_t d3, Register b3);   // branch prediction    -- EC12
+  inline void z_bprp( int64_t m1, int64_t i2, int64_t i3);                // branch prediction    -- EC12
+
+  //-------------------------------
+  // Transaction Control
+  //-------------------------------
+  inline void z_tbegin(int64_t d1, Register b1, int64_t i2);          // begin transaction               -- EC12
+  inline void z_tbeginc(int64_t d1, Register b1, int64_t i2);         // begin transaction (constrained) -- EC12
+  inline void z_tend();                                               // end transaction                 -- EC12
+  inline void z_tabort(int64_t d2, Register b2);                      // abort transaction               -- EC12
+  inline void z_etnd(Register r1);                                    // extract tx nesting depth        -- EC12
+  inline void z_ppa(Register r1, Register r2, int64_t m3);            // perform processor assist        -- EC12
+
+  //---------------------------------
+  // Conditional Execution
+  //---------------------------------
+  inline void z_locr( Register r1, Register r2, branch_condition cc);             // if (cc) load r1 = r2               ; int32 -- z196
+  inline void z_locgr(Register r1, Register r2, branch_condition cc);             // if (cc) load r1 = r2               ; int64 -- z196
+  inline void z_loc(  Register r1, int64_t d2, Register b2, branch_condition cc); // if (cc) load r1 = *(d2_simm20+b2)  ; int32 -- z196
+  inline void z_locg( Register r1, int64_t d2, Register b2, branch_condition cc); // if (cc) load r1 = *(d2_simm20+b2)  ; int64 -- z196
+  inline void z_loc(  Register r1, const Address& a, branch_condition cc);        // if (cc) load r1 = *(a)             ; int32 -- z196
+  inline void z_locg( Register r1, const Address& a, branch_condition cc);        // if (cc) load r1 = *(a)             ; int64 -- z196
+  inline void z_stoc( Register r1, int64_t d2, Register b2, branch_condition cc); // if (cc) store *(d2_simm20+b2) = r1 ; int32 -- z196
+  inline void z_stocg(Register r1, int64_t d2, Register b2, branch_condition cc); // if (cc) store *(d2_simm20+b2) = r1 ; int64 -- z196
+
+
+  // Complex CISC instructions
+  // ==========================
+
+  inline void z_cksm(Register r1, Register r2);                       // checksum. This is NOT CRC32
+  inline void z_km(  Register r1, Register r2);                       // cipher message
+  inline void z_kmc( Register r1, Register r2);                       // cipher message with chaining
+  inline void z_kimd(Register r1, Register r2);                       // msg digest (SHA)
+  inline void z_klmd(Register r1, Register r2);                       // msg digest (SHA)
+  inline void z_kmac(Register r1, Register r2);                       // msg authentication code
+
+  inline void z_ex(Register r1, int64_t d2, Register x2, Register b2);// execute
+  inline void z_exrl(Register r1, int64_t i2);                        // execute relative long         -- z10
+  inline void z_exrl(Register r1, address a2);                        // execute relative long         -- z10
+
+  inline void z_ectg(int64_t d1, Register b1, int64_t d2, Register b2, Register r3);  // extract cpu time
+  inline void z_ecag(Register r1, Register r3, int64_t d2, Register b2);              // extract CPU attribute
+
+  inline void z_srst(Register r1, Register r2);                       // search string
+  inline void z_srstu(Register r1, Register r2);                      // search string unicode
+
+  inline void z_mvc(const Address& d, const Address& s, int64_t l);               // move l bytes
+  inline void z_mvc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2); // move l+1 bytes
+  inline void z_mvcle(Register r1, Register r3, int64_t d2, Register b2=Z_R0);    // move region of memory
+
+  inline void z_stfle(int64_t d2, Register b2);                            // store facility list extended
+
+  inline void z_nc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2);// and *(d1+b1) = *(d1+l+b1) & *(d2+b2) ; d1, d2: uimm12, ands l+1 bytes
+  inline void z_oc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2);//  or *(d1+b1) = *(d1+l+b1) | *(d2+b2) ; d1, d2: uimm12,  ors l+1 bytes
+  inline void z_xc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2);// xor *(d1+b1) = *(d1+l+b1) ^ *(d2+b2) ; d1, d2: uimm12, xors l+1 bytes
+  inline void z_nc(Address dst, int64_t len, Address src2);                     // and *dst = *dst & *src2, ands len bytes in memory
+  inline void z_oc(Address dst, int64_t len, Address src2);                     //  or *dst = *dst | *src2,  ors len bytes in memory
+  inline void z_xc(Address dst, int64_t len, Address src2);                     // xor *dst = *dst ^ *src2, xors len bytes in memory
+
+  // compare instructions
+  inline void z_clc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2);  // compare (*(d1_uimm12+b1), *(d1_uimm12+b1)) ; compare l bytes
+  inline void z_clcle(Register r1, Register r3, int64_t d2, Register b2);  // compare logical long extended, see docu
+  inline void z_clclu(Register r1, Register r3, int64_t d2, Register b2);  // compare logical long unicode, see docu
+
+  // Translate characters
+  inline void z_troo(Register r1, Register r2, int64_t m3);
+  inline void z_trot(Register r1, Register r2, int64_t m3);
+  inline void z_trto(Register r1, Register r2, int64_t m3);
+  inline void z_trtt(Register r1, Register r2, int64_t m3);
+
+
+  // Floatingpoint instructions
+  // ==========================
+
+  // compare instructions
+  inline void z_cebr(FloatRegister r1, FloatRegister r2);                     // compare (r1, r2)                ; float
+  inline void z_ceb(FloatRegister r1, int64_t d2, Register x2, Register b2);  // compare (r1, *(d2_imm12+x2+b2)) ; float
+  inline void z_ceb(FloatRegister r1, const Address &a);                      // compare (r1, *(d2_imm12+x2+b2)) ; float
+  inline void z_cdbr(FloatRegister r1, FloatRegister r2);                     // compare (r1, r2)                ; double
+  inline void z_cdb(FloatRegister r1, int64_t d2, Register x2, Register b2);  // compare (r1, *(d2_imm12+x2+b2)) ; double
+  inline void z_cdb(FloatRegister r1, const Address &a);                      // compare (r1, *(d2_imm12+x2+b2)) ; double
+
+  // load instructions
+  inline void z_le( FloatRegister r1, int64_t d2, Register x2, Register b2);   // load r1 = *(d2_uimm12+x2+b2) ; float
+  inline void z_ley(FloatRegister r1, int64_t d2, Register x2, Register b2);   // load r1 = *(d2_imm20+x2+b2)  ; float
+  inline void z_ld( FloatRegister r1, int64_t d2, Register x2, Register b2);   // load r1 = *(d2_uimm12+x2+b2) ; double
+  inline void z_ldy(FloatRegister r1, int64_t d2, Register x2, Register b2);   // load r1 = *(d2_imm20+x2+b2)  ; double
+  inline void z_le( FloatRegister r1, const Address &a);                       // load r1 = *(a)               ; float
+  inline void z_ley(FloatRegister r1, const Address &a);                       // load r1 = *(a)               ; float
+  inline void z_ld( FloatRegister r1, const Address &a);                       // load r1 = *(a)               ; double
+  inline void z_ldy(FloatRegister r1, const Address &a);                       // load r1 = *(a)               ; double
+
+  // store instructions
+  inline void z_ste( FloatRegister r1, int64_t d2, Register x2, Register b2);  // store *(d2_uimm12+x2+b2) = r1  ; float
+  inline void z_stey(FloatRegister r1, int64_t d2, Register x2, Register b2);  // store *(d2_imm20+x2+b2)  = r1  ; float
+  inline void z_std( FloatRegister r1, int64_t d2, Register x2, Register b2);  // store *(d2_uimm12+x2+b2) = r1  ; double
+  inline void z_stdy(FloatRegister r1, int64_t d2, Register x2, Register b2);  // store *(d2_imm20+x2+b2)  = r1  ; double
+  inline void z_ste( FloatRegister r1, const Address &a);                      // store *(a)               = r1  ; float
+  inline void z_stey(FloatRegister r1, const Address &a);                      // store *(a)               = r1  ; float
+  inline void z_std( FloatRegister r1, const Address &a);                      // store *(a)               = r1  ; double
+  inline void z_stdy(FloatRegister r1, const Address &a);                      // store *(a)               = r1  ; double
+
+  // load and store immediates
+  inline void z_lzer(FloatRegister r1);                                 // r1 = 0     ; single
+  inline void z_lzdr(FloatRegister r1);                                 // r1 = 0     ; double
+
+  // Move and Convert instructions
+  inline void z_ler(FloatRegister r1, FloatRegister r2);                // move         r1 = r2 ; float
+  inline void z_ldr(FloatRegister r1, FloatRegister r2);                // move         r1 = r2 ; double
+  inline void z_ledbr(FloatRegister r1, FloatRegister r2);              // conv / round r1 = r2 ; float <- double
+  inline void z_ldebr(FloatRegister r1, FloatRegister r2);              // conv         r1 = r2 ; double <- float
+
+  // move between integer and float registers
+  inline void z_cefbr( FloatRegister r1, Register r2);                  // r1 = r2; float  <-- int32
+  inline void z_cdfbr( FloatRegister r1, Register r2);                  // r1 = r2; double <-- int32
+  inline void z_cegbr( FloatRegister r1, Register r2);                  // r1 = r2; float  <-- int64
+  inline void z_cdgbr( FloatRegister r1, Register r2);                  // r1 = r2; double <-- int64
+
+  // rounding mode for float-2-int conversions
+  inline void z_cfebr(Register r1, FloatRegister r2, RoundingMode m);   // conv r1 = r2  ; int32 <-- float
+  inline void z_cfdbr(Register r1, FloatRegister r2, RoundingMode m);   // conv r1 = r2  ; int32 <-- double
+  inline void z_cgebr(Register r1, FloatRegister r2, RoundingMode m);   // conv r1 = r2  ; int64 <-- float
+  inline void z_cgdbr(Register r1, FloatRegister r2, RoundingMode m);   // conv r1 = r2  ; int64 <-- double
+
+  inline void z_ldgr(FloatRegister r1, Register r2);   // fr1 = r2  ; what kind of conversion?  -- z10
+  inline void z_lgdr(Register r1, FloatRegister r2);   // r1  = fr2 ; what kind of conversion?  -- z10
+
+
+  // ADD
+  inline void z_aebr(FloatRegister f1, FloatRegister f2);                      // f1 = f1 + f2               ; float
+  inline void z_adbr(FloatRegister f1, FloatRegister f2);                      // f1 = f1 + f2               ; double
+  inline void z_aeb( FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 + *(d2+x2+b2)      ; float
+  inline void z_adb( FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 + *(d2+x2+b2)      ; double
+  inline void z_aeb( FloatRegister f1, const Address& a);                      // f1 = f1 + *(a)             ; float
+  inline void z_adb( FloatRegister f1, const Address& a);                      // f1 = f1 + *(a)             ; double
+
+  // SUB
+  inline void z_sebr(FloatRegister f1, FloatRegister f2);                      // f1 = f1 - f2               ; float
+  inline void z_sdbr(FloatRegister f1, FloatRegister f2);                      // f1 = f1 - f2               ; double
+  inline void z_seb( FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 - *(d2+x2+b2)      ; float
+  inline void z_sdb( FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 - *(d2+x2+b2)      ; double
+  inline void z_seb( FloatRegister f1, const Address& a);                      // f1 = f1 - *(a)             ; float
+  inline void z_sdb( FloatRegister f1, const Address& a);                      // f1 = f1 - *(a)             ; double
+  // negate
+  inline void z_lcebr(FloatRegister r1, FloatRegister r2);                     // neg r1 = -r2   ; float
+  inline void z_lcdbr(FloatRegister r1, FloatRegister r2);                     // neg r1 = -r2   ; double
+
+  // Absolute value, monadic if fr2 == noreg.
+  inline void z_lpdbr( FloatRegister fr1, FloatRegister fr2 = fnoreg);         // fr1 = |fr2|
+
+
+  // MUL
+  inline void z_meebr(FloatRegister f1, FloatRegister f2);                      // f1 = f1 * f2               ; float
+  inline void z_mdbr( FloatRegister f1, FloatRegister f2);                      // f1 = f1 * f2               ; double
+  inline void z_meeb( FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 * *(d2+x2+b2)      ; float
+  inline void z_mdb(  FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 * *(d2+x2+b2)      ; double
+  inline void z_meeb( FloatRegister f1, const Address& a);
+  inline void z_mdb(  FloatRegister f1, const Address& a);
+
+  // DIV
+  inline void z_debr( FloatRegister f1, FloatRegister f2);                      // f1 = f1 / f2               ; float
+  inline void z_ddbr( FloatRegister f1, FloatRegister f2);                      // f1 = f1 / f2               ; double
+  inline void z_deb(  FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 / *(d2+x2+b2)      ; float
+  inline void z_ddb(  FloatRegister f1, int64_t d2, Register x2, Register b2);  // f1 = f1 / *(d2+x2+b2)      ; double
+  inline void z_deb(  FloatRegister f1, const Address& a);                      // f1 = f1 / *(a)             ; float
+  inline void z_ddb(  FloatRegister f1, const Address& a);                      // f1 = f1 / *(a)             ; double
+
+  // square root
+  inline void z_sqdbr(FloatRegister fr1, FloatRegister fr2);                    // fr1 = sqrt(fr2)            ; double
+  inline void z_sqdb( FloatRegister fr1, int64_t d2, Register x2, Register b2); // fr1 = srqt( *(d2+x2+b2)
+  inline void z_sqdb( FloatRegister fr1, int64_t d2, Register b2);              // fr1 = srqt( *(d2+b2)
+
+  // Nop instruction
+  // ===============
+
+  // branch never (nop)
+  inline void z_nop();
+
+  // ===============================================================================================
+
+  // Simplified emitters:
+  // ====================
+
+
+  // Some memory instructions without index register (just convenience).
+  inline void z_layz(Register r1, int64_t d2, Register b2 = Z_R0);
+  inline void z_lay(Register r1, int64_t d2, Register b2);
+  inline void z_laz(Register r1, int64_t d2, Register b2);
+  inline void z_la(Register r1, int64_t d2, Register b2);
+  inline void z_l(Register r1, int64_t d2, Register b2);
+  inline void z_ly(Register r1, int64_t d2, Register b2);
+  inline void z_lg(Register r1, int64_t d2, Register b2);
+  inline void z_st(Register r1, int64_t d2, Register b2);
+  inline void z_sty(Register r1, int64_t d2, Register b2);
+  inline void z_stg(Register r1, int64_t d2, Register b2);
+  inline void z_lgf(Register r1, int64_t d2, Register b2);
+  inline void z_lgh(Register r1, int64_t d2, Register b2);
+  inline void z_llgh(Register r1, int64_t d2, Register b2);
+  inline void z_llgf(Register r1, int64_t d2, Register b2);
+  inline void z_lgb(Register r1, int64_t d2, Register b2);
+  inline void z_cl( Register r1, int64_t d2, Register b2);
+  inline void z_c(Register r1, int64_t d2, Register b2);
+  inline void z_cg(Register r1, int64_t d2, Register b2);
+  inline void z_sh(Register r1, int64_t d2, Register b2);
+  inline void z_shy(Register r1, int64_t d2, Register b2);
+  inline void z_ste(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_std(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_stdy(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_stey(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_ld(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_ldy(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_le(FloatRegister r1, int64_t d2, Register b2);
+  inline void z_ley(FloatRegister r1, int64_t d2, Register b2);
+
+  inline void z_agf(Register r1, int64_t d2, Register b2);
+
+  inline void z_exrl(Register r1, Label& L);
+  inline void z_larl(Register r1, Label& L);
+  inline void z_bru( Label& L);
+  inline void z_brul(Label& L);
+  inline void z_brul(address a);
+  inline void z_brh( Label& L);
+  inline void z_brl( Label& L);
+  inline void z_bre( Label& L);
+  inline void z_brnh(Label& L);
+  inline void z_brnl(Label& L);
+  inline void z_brne(Label& L);
+  inline void z_brz( Label& L);
+  inline void z_brnz(Label& L);
+  inline void z_brnaz(Label& L);
+  inline void z_braz(Label& L);
+  inline void z_brnp(Label& L);
+
+  inline void z_btrue( Label& L);
+  inline void z_bfalse(Label& L);
+
+  inline void z_brno( Label& L);
+
+
+  inline void z_basr(Register r1, Register r2);
+  inline void z_brasl(Register r1, address a);
+  inline void z_brct(Register r1, address a);
+  inline void z_brct(Register r1, Label& L);
+
+  inline void z_brxh(Register r1, Register r3, address a);
+  inline void z_brxh(Register r1, Register r3, Label& L);
+
+  inline void z_brxle(Register r1, Register r3, address a);
+  inline void z_brxle(Register r1, Register r3, Label& L);
+
+  inline void z_brxhg(Register r1, Register r3, address a);
+  inline void z_brxhg(Register r1, Register r3, Label& L);
+
+  inline void z_brxlg(Register r1, Register r3, address a);
+  inline void z_brxlg(Register r1, Register r3, Label& L);
+
+  // Ppopulation count intrinsics.
+  inline void z_flogr(Register r1, Register r2);    // find leftmost one
+  inline void z_popcnt(Register r1, Register r2);   // population count
+  inline void z_ahhhr(Register r1, Register r2, Register r3);   // ADD halfword high high
+  inline void z_ahhlr(Register r1, Register r2, Register r3);   // ADD halfword high low
+
+  inline void z_tam();
+  inline void z_stck(int64_t d2, Register b2);
+  inline void z_stckf(int64_t d2, Register b2);
+  inline void z_stmg(Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_lmg(Register r1, Register r3, int64_t d2, Register b2);
+
+  inline void z_cs( Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_csy(Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_csg(Register r1, Register r3, int64_t d2, Register b2);
+  inline void z_cs( Register r1, Register r3, const Address& a);
+  inline void z_csy(Register r1, Register r3, const Address& a);
+  inline void z_csg(Register r1, Register r3, const Address& a);
+
+  inline void z_cvd(Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_cvdg(Register r1, int64_t d2, Register x2, Register b2);
+  inline void z_cvd(Register r1, int64_t d2, Register b2);
+  inline void z_cvdg(Register r1, int64_t d2, Register b2);
+
+  // Instruction queries:
+  // instruction properties and recognize emitted instructions
+  // ===========================================================
+
+  static int nop_size() { return 2; }
+
+  static int z_brul_size() { return 6; }
+
+  static bool is_z_basr(short x) {
+    return (BASR_ZOPC == (x & BASR_MASK));
+  }
+  static bool is_z_algr(long x) {
+    return (ALGR_ZOPC == (x & RRE_MASK));
+  }
+  static bool is_z_lb(long x) {
+    return (LB_ZOPC == (x & LB_MASK));
+  }
+  static bool is_z_lh(int x) {
+    return (LH_ZOPC == (x & LH_MASK));
+  }
+  static bool is_z_l(int x) {
+    return (L_ZOPC == (x & L_MASK));
+  }
+  static bool is_z_lgr(long x) {
+    return (LGR_ZOPC == (x & RRE_MASK));
+  }
+  static bool is_z_ly(long x) {
+    return (LY_ZOPC == (x & LY_MASK));
+  }
+  static bool is_z_lg(long x) {
+    return (LG_ZOPC == (x & LG_MASK));
+  }
+  static bool is_z_llgh(long x) {
+    return (LLGH_ZOPC == (x & LLGH_MASK));
+  }
+  static bool is_z_llgf(long x) {
+    return (LLGF_ZOPC == (x & LLGF_MASK));
+  }
+  static bool is_z_le(int x) {
+    return (LE_ZOPC == (x & LE_MASK));
+  }
+  static bool is_z_ld(int x) {
+    return (LD_ZOPC == (x & LD_MASK));
+  }
+  static bool is_z_st(int x) {
+    return (ST_ZOPC == (x & ST_MASK));
+  }
+  static bool is_z_stc(int x) {
+    return (STC_ZOPC == (x & STC_MASK));
+  }
+  static bool is_z_stg(long x) {
+    return (STG_ZOPC == (x & STG_MASK));
+  }
+  static bool is_z_sth(int x) {
+    return (STH_ZOPC == (x & STH_MASK));
+  }
+  static bool is_z_ste(int x) {
+    return (STE_ZOPC == (x & STE_MASK));
+  }
+  static bool is_z_std(int x) {
+    return (STD_ZOPC == (x & STD_MASK));
+  }
+  static bool is_z_slag(long x) {
+    return (SLAG_ZOPC == (x & SLAG_MASK));
+  }
+  static bool is_z_tmy(long x) {
+    return (TMY_ZOPC == (x & TMY_MASK));
+  }
+  static bool is_z_tm(long x) {
+    return ((unsigned int)TM_ZOPC == (x & (unsigned int)TM_MASK));
+  }
+  static bool is_z_bcr(long x) {
+    return (BCR_ZOPC == (x & BCR_MASK));
+  }
+  static bool is_z_nop(long x) {
+    return is_z_bcr(x) && ((x & 0x00ff) == 0);
+  }
+  static bool is_z_nop(address x) {
+    return is_z_nop(* (short *) x);
+  }
+  static bool is_z_br(long x) {
+    return is_z_bcr(x) && ((x & 0x00f0) == 0x00f0);
+  }
+  static bool is_z_brc(long x, int cond) {
+    return ((unsigned int)BRC_ZOPC == (x & BRC_MASK)) && ((cond<<20) == (x & 0x00f00000U));
+  }
+  // Make use of lightweight sync.
+  static bool is_z_sync_full(long x) {
+    return is_z_bcr(x) && (((x & 0x00f0)>>4)==bcondFullSync) && ((x & 0x000f)==0x0000);
+  }
+  static bool is_z_sync_light(long x) {
+    return is_z_bcr(x) && (((x & 0x00f0)>>4)==bcondLightSync) && ((x & 0x000f)==0x0000);
+  }
+  static bool is_z_sync(long x) {
+    return is_z_sync_full(x) || is_z_sync_light(x);
+  }
+
+  static bool is_z_brasl(long x) {
+    return (BRASL_ZOPC == (x & BRASL_MASK));
+  }
+  static bool is_z_brasl(address a) {
+  long x = (*((long *)a))>>16;
+   return is_z_brasl(x);
+  }
+  static bool is_z_larl(long x) {
+    return (LARL_ZOPC == (x & LARL_MASK));
+  }
+  static bool is_z_lgrl(long x) {
+    return (LGRL_ZOPC == (x & LGRL_MASK));
+  }
+  static bool is_z_lgrl(address a) {
+  long x = (*((long *)a))>>16;
+   return is_z_lgrl(x);
+  }
+
+  static bool is_z_lghi(unsigned long x) {
+    return (unsigned int)LGHI_ZOPC == (x & (unsigned int)LGHI_MASK);
+  }
+
+  static bool is_z_llill(unsigned long x) {
+    return (unsigned int)LLILL_ZOPC == (x & (unsigned int)LLI_MASK);
+  }
+  static bool is_z_llilh(unsigned long x) {
+    return (unsigned int)LLILH_ZOPC == (x & (unsigned int)LLI_MASK);
+  }
+  static bool is_z_llihl(unsigned long x) {
+    return (unsigned int)LLIHL_ZOPC == (x & (unsigned int)LLI_MASK);
+  }
+  static bool is_z_llihh(unsigned long x) {
+    return (unsigned int)LLIHH_ZOPC == (x & (unsigned int)LLI_MASK);
+  }
+  static bool is_z_llilf(unsigned long x) {
+    return LLILF_ZOPC == (x & LLIF_MASK);
+  }
+  static bool is_z_llihf(unsigned long x) {
+    return LLIHF_ZOPC == (x & LLIF_MASK);
+  }
+
+  static bool is_z_iill(unsigned long x) {
+    return (unsigned int)IILL_ZOPC == (x & (unsigned int)II_MASK);
+  }
+  static bool is_z_iilh(unsigned long x) {
+    return (unsigned int)IILH_ZOPC == (x & (unsigned int)II_MASK);
+  }
+  static bool is_z_iihl(unsigned long x) {
+    return (unsigned int)IIHL_ZOPC == (x & (unsigned int)II_MASK);
+  }
+  static bool is_z_iihh(unsigned long x) {
+    return (unsigned int)IIHH_ZOPC == (x & (unsigned int)II_MASK);
+  }
+  static bool is_z_iilf(unsigned long x) {
+    return IILF_ZOPC == (x & IIF_MASK);
+  }
+  static bool is_z_iihf(unsigned long x) {
+    return IIHF_ZOPC == (x & IIF_MASK);
+  }
+
+  static inline bool is_equal(unsigned long inst, unsigned long idef);
+  static inline bool is_equal(unsigned long inst, unsigned long idef, unsigned long imask);
+  static inline bool is_equal(address iloc, unsigned long idef);
+  static inline bool is_equal(address iloc, unsigned long idef, unsigned long imask);
+
+  static inline bool is_sigtrap_range_check(address pc);
+  static inline bool is_sigtrap_zero_check(address pc);
+
+  //-----------------
+  // memory barriers
+  //-----------------
+  // machine barrier instructions:
+  //
+  // - z_sync            Two-way memory barrier, aka fence.
+  //                     Only load-after-store-order is not guaranteed in the
+  //                     z/Architecture memory model, i.e. only 'fence' is needed.
+  //
+  // semantic barrier instructions:
+  // (as defined in orderAccess.hpp)
+  //
+  // - z_release         orders Store|Store,   empty implementation
+  //                            Load|Store
+  // - z_acquire         orders Load|Store,    empty implementation
+  //                            Load|Load
+  // - z_fence           orders Store|Store,   implemented as z_sync.
+  //                            Load|Store,
+  //                            Load|Load,
+  //                            Store|Load
+  //
+  // For this implementation to be correct, we need H/W fixes on (very) old H/W:
+  //          For z990, it is Driver-55:  MCL232 in the J13484 (i390/ML) Stream.
+  //          For z9,   it is Driver-67:  MCL065 in the G40963 (i390/ML) Stream.
+  // These drivers are a prereq. Otherwise, memory synchronization will not work.
+
+  inline void z_sync();
+  inline void z_release();
+  inline void z_acquire();
+  inline void z_fence();
+
+  // Creation
+  Assembler(CodeBuffer* code) : AbstractAssembler(code) { }
+
+};
+
+#endif // CPU_S390_VM_ASSEMBLER_S390_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/assembler_s390.inline.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,1015 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_ASSEMBLER_S390_INLINE_HPP
+#define CPU_S390_VM_ASSEMBLER_S390_INLINE_HPP
+
+#include "asm/assembler.inline.hpp"
+#include "asm/codeBuffer.hpp"
+#include "code/codeCache.hpp"
+
+// Convention: Use Z_R0 and Z_R1 instead of Z_scratch_* in all
+// assembler_s390.* files.
+
+// Local implementation of byte emitters to help inlining.
+inline void Assembler::emit_16(int x) {
+  CodeSection*       cs = code_section();
+  address      code_pos = pc();
+  *(unsigned short*)code_pos = (unsigned short)x;
+  cs->set_end( code_pos + sizeof(unsigned short));
+}
+
+inline void Assembler::emit_32(int x) {
+  CodeSection*       cs = code_section();
+  address      code_pos = pc();
+  *(jint*)code_pos = (jint)x;
+  cs->set_end( code_pos + sizeof( jint));
+}
+
+inline void Assembler::emit_48(long x) {
+  CodeSection*       cs = code_section();
+  address      code_pos = pc();
+  *(unsigned short*)code_pos = (unsigned short)(x>>32);
+  *(jint*)(code_pos+sizeof(unsigned short)) = (jint)x;
+  cs->set_end( code_pos + sizeof( jint) + sizeof( unsigned short));
+}
+
+// Support lightweight sync (from z196). Experimental as of now. For explanation see *.hpp file.
+inline void Assembler::z_sync() {
+  if (VM_Version::has_FastSync()) {
+    z_bcr(bcondLightSync, Z_R0);
+  } else {
+    z_bcr(bcondFullSync, Z_R0);
+  }
+}
+inline void Assembler::z_release() { }
+inline void Assembler::z_acquire() { }
+inline void Assembler::z_fence()   { z_sync(); }
+
+inline void Assembler::z_illtrap() {
+  emit_16(0);
+}
+inline void Assembler::z_illtrap(int id) {
+  emit_16(id & 0x00ff);
+}
+inline void Assembler::z_illtrap_eyecatcher(unsigned short xpattern, unsigned short pattern) {
+  z_llill(Z_R0, xpattern);
+  z_iilh(Z_R0, pattern);
+  z_illtrap((unsigned int)xpattern);
+}
+
+inline void Assembler::z_lhrl(Register r1, int64_t i2)  { emit_48( LHRL_ZOPC   | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_lrl(Register r1, int64_t i2)   { emit_48( LRL_ZOPC    | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_lghrl(Register r1, int64_t i2) { emit_48( LGHRL_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_lgfrl(Register r1, int64_t i2) { emit_48( LGFRL_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_lgrl(Register r1, int64_t i2)  { emit_48( LGRL_ZOPC   | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_llhrl(Register r1, int64_t i2) { emit_48( LLHRL_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_llghrl(Register r1, int64_t i2){ emit_48( LLGHRL_ZOPC | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_llgfrl(Register r1, int64_t i2){ emit_48( LLGFRL_ZOPC | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+
+inline void Assembler::z_sthrl(Register r1, int64_t i2) { emit_48( STHRL_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_strl(Register r1, int64_t i2)  { emit_48( STRL_ZOPC   | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_stgrl(Register r1, int64_t i2) { emit_48( STGRL_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+
+inline void Assembler::z_cksm(Register r1, Register r2) { emit_32( CKSM_ZOPC   | regt(r1, 24, 32) | regt(r2, 28, 32)); }
+inline void Assembler::z_km(  Register r1, Register r2) { emit_32( KM_ZOPC     | regt(r1, 24, 32) | regt(r2, 28, 32)); }
+inline void Assembler::z_kmc( Register r1, Register r2) { emit_32( KMC_ZOPC    | regt(r1, 24, 32) | regt(r2, 28, 32)); }
+inline void Assembler::z_kimd(Register r1, Register r2) { emit_32( KIMD_ZOPC   | regt(r1, 24, 32) | regt(r2, 28, 32)); }
+inline void Assembler::z_klmd(Register r1, Register r2) { emit_32( KLMD_ZOPC   | regt(r1, 24, 32) | regt(r2, 28, 32)); }
+inline void Assembler::z_kmac(Register r1, Register r2) { emit_32( KMAC_ZOPC   | regt(r1, 24, 32) | regt(r2, 28, 32)); }
+
+inline void Assembler::z_exrl(Register r1, int64_t i2)  { emit_48( EXRL_ZOPC   | regt(r1, 8, 48) | simm32(i2, 16, 48)); }                             // z10
+inline void Assembler::z_exrl(Register r1, address a2)  { emit_48( EXRL_ZOPC   | regt(r1, 8, 48) | simm32(RelAddr::pcrel_off32(a2, pc()), 16, 48)); } // z10
+
+inline void Assembler::z_ectg(int64_t d1, Register b1, int64_t d2, Register b2, Register r3) { emit_48( ECTG_ZOPC | reg(r3, 8, 48) | uimm12(d1, 20, 48) | reg(b1, 16, 48) | uimm12(d2, 36, 48) | reg(b2, 32, 48)); }
+inline void Assembler::z_ecag(Register r1, Register r3, int64_t d2, Register b2)             { emit_48( ECAG_ZOPC | reg(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | reg(b2, 16, 48)); }
+
+
+//------------------------------
+// Interlocked-Update
+//------------------------------
+inline void Assembler::z_laa(  Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAA_ZOPC   | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_laag( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAAG_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_laal( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAAL_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_laalg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAALG_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_lan(  Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAN_ZOPC   | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_lang( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LANG_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_lax(  Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAX_ZOPC   | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_laxg( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAXG_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_lao(  Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAO_ZOPC   | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+inline void Assembler::z_laog( Register r1, Register r3, int64_t d2, Register b2) { emit_48( LAOG_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | regz(b2, 16, 48)); }
+
+inline void Assembler::z_laa(  Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_laa(  r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_laag( Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_laag( r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_laal( Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_laal( r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_laalg(Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_laalg(r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_lan(  Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_lan(  r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_lang( Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_lang( r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_lax(  Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_lax(  r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_laxg( Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_laxg( r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_lao(  Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_lao(  r1, r3, a.disp12(), a.base()); }
+inline void Assembler::z_laog( Register r1, Register r3, const Address& a) { assert(!a.has_index(), " no index reg allowed"); z_laog( r1, r3, a.disp12(), a.base()); }
+
+//--------------------------------
+// Execution Prediction
+//--------------------------------
+inline void Assembler::z_pfd(  int64_t m1, int64_t d2, Register x2, Register b2) { emit_48( PFD_ZOPC   | uimm4(m1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_pfd(  int64_t m1, Address a)                            { z_pfd(m1, a.disp(), a.indexOrR0(), a.base()); }
+inline void Assembler::z_pfdrl(int64_t m1, int64_t i2)                           { emit_48( PFDRL_ZOPC | uimm4(m1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_bpp(  int64_t m1, int64_t i2, int64_t d3, Register b3)  { emit_48( BPP_ZOPC   | uimm4(m1, 8, 48) | uimm12(d3, 20, 48) | reg(b3, 16, 48) | simm16(i2, 32, 48)); }
+inline void Assembler::z_bprp( int64_t m1, int64_t i2, int64_t i3)               { emit_48( BPRP_ZOPC  | uimm4(m1, 8, 48) | simm12(i2, 12, 48) | simm24(i3, 24, 48)); }
+
+//-------------------------------
+// Transaction Control
+//-------------------------------
+inline void Assembler::z_tbegin( int64_t d1, Register b1, int64_t i2) { emit_48( TBEGIN_ZOPC  | uimm12(d1, 20, 48) | reg(b1, 16, 48) | uimm16(i2, 32, 48)); }
+inline void Assembler::z_tbeginc(int64_t d1, Register b1, int64_t i2) { emit_48( TBEGINC_ZOPC | uimm12(d1, 20, 48) | reg(b1, 16, 48) | uimm16(i2, 32, 48)); }
+inline void Assembler::z_tend()                                       { emit_32( TEND_ZOPC); }
+inline void Assembler::z_tabort( int64_t d2, Register b2)             { emit_32( TABORT_ZOPC  | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_etnd(Register r1)                            { emit_32( ETND_ZOPC    | regt(r1, 24, 32)); }
+inline void Assembler::z_ppa(Register r1, Register r2, int64_t m3)    { emit_32( PPA_ZOPC     | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+
+//---------------------------------
+// Conditional Execution
+//---------------------------------
+inline void Assembler::z_locr(  Register r1, Register r2, branch_condition cc)             { emit_32( LOCR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | uimm4(cc, 16, 32)); }               // z196
+inline void Assembler::z_locgr( Register r1, Register r2, branch_condition cc)             { emit_32( LOCGR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | uimm4(cc, 16, 32)); }               // z196
+inline void Assembler::z_loc(   Register r1, int64_t d2, Register b2, branch_condition cc) { emit_48( LOC_ZOPC   | regt(r1,  8, 48) | simm20(d2) | regz(b2, 16, 48) | uimm4(cc, 12, 48)); } // z196
+inline void Assembler::z_locg(  Register r1, int64_t d2, Register b2, branch_condition cc) { emit_48( LOCG_ZOPC  | regt(r1,  8, 48) | simm20(d2) | regz(b2, 16, 48) | uimm4(cc, 12, 48)); } // z196
+inline void Assembler::z_loc(   Register r1, const Address &a, branch_condition cc)        { z_loc(r1, a.disp(), a.base(), cc); }
+inline void Assembler::z_locg(  Register r1, const Address &a, branch_condition cc)        { z_locg(r1, a.disp(), a.base(), cc); }
+inline void Assembler::z_stoc(  Register r1, int64_t d2, Register b2, branch_condition cc) { emit_48( STOC_ZOPC  | regt(r1,  8, 48) | simm20(d2) | regz(b2, 16, 48) | uimm4(cc, 12, 48)); } // z196
+inline void Assembler::z_stocg( Register r1, int64_t d2, Register b2, branch_condition cc) { emit_48( STOCG_ZOPC | regt(r1,  8, 48) | simm20(d2) | regz(b2, 16, 48) | uimm4(cc, 12, 48)); } // z196
+
+inline void Assembler::z_srst( Register r1, Register r2) { emit_32( SRST_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_srstu(Register r1, Register r2) { emit_32( SRSTU_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+//---------------------------------
+// Address calculation
+//---------------------------------
+inline void Assembler::z_layz(Register r1, int64_t d2, Register x2, Register b2) { emit_48( LAY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | reg(b2, 16, 48)); }
+inline void Assembler::z_lay( Register r1, const Address &a)                     { z_layz(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lay( Register r1, int64_t d2, Register x2, Register b2) { emit_48( LAY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_laz( Register r1, int64_t d2, Register x2, Register b2) { emit_32( LA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_la(  Register r1, const Address &a)                     { z_laz(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_la(  Register r1, int64_t d2, Register x2, Register b2) { emit_32( LA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32));}
+inline void Assembler::z_larl(Register r1, int64_t i2)    { emit_48( LARL_ZOPC | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_larl(Register r1, address a)     { emit_48( LARL_ZOPC | regt(r1, 8, 48) | simm32(RelAddr::pcrel_off32(a, pc()), 16, 48)); }
+
+inline void Assembler::z_lr(Register r1, Register r2)                          { emit_16( LR_ZOPC | regt(r1,8,16) | reg(r2,12,16)); }
+inline void Assembler::z_lgr(Register r1, Register r2)                         { emit_32( LGR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_lh(Register r1, int64_t d2, Register x2, Register b2) { emit_32( LH_ZOPC | 0 << 16 | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_lh(Register r1, const Address &a)                     { z_lh(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_l(Register r1, int64_t d2, Register x2, Register b2)  { emit_32( L_ZOPC | 0 << 16 | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_l(Register r1, const Address &a)                      { z_l(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lg(Register r1, int64_t d2, Register x2, Register b2) { emit_48( LG_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_lg(Register r1, const Address &a)                     { z_lg(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_lbr(  Register r1, Register r2) { emit_32( LBR_ZOPC   | regt(r1, 24, 32) | reg( r2, 28, 32)); }
+inline void Assembler::z_lhr(  Register r1, Register r2) { emit_32( LHR_ZOPC   | regt(r1, 24, 32) | reg( r2, 28, 32)); }
+inline void Assembler::z_lgbr( Register r1, Register r2) { emit_32( LGBR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_lghr( Register r1, Register r2) { emit_32( LGHR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_lgfr( Register r1, Register r2) { emit_32( LGFR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_llhr( Register r1, Register r2) { emit_32( LLHR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_llgcr(Register r1, Register r2) { emit_32( LLGCR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_llghr(Register r1, Register r2) { emit_32( LLGHR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_llgfr(Register r1, Register r2) { emit_32( LLGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+inline void Assembler::z_sth(Register r1, const Address &a)                     { z_sth(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sth(Register r1, int64_t d2, Register x2, Register b2) { emit_32( STH_ZOPC | reg(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_st( Register r1, const Address& d)                     { z_st(r1, d.disp(), d.indexOrR0(), d.base()); }
+inline void Assembler::z_st( Register r1, int64_t d2, Register x2, Register b2) { emit_32( ST_ZOPC  | reg(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stg(Register r1, const Address& d)                     { z_stg(r1, d.disp(), d.indexOrR0(), d.base()); }
+inline void Assembler::z_stg(Register r1, int64_t d2, Register x2, Register b2) { emit_48( STG_ZOPC | reg(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+
+inline void Assembler::z_stcm (Register r1, int64_t m3, int64_t d2, Register b2) { emit_32( STCM_ZOPC  | regt(r1, 8, 32) | uimm4(m3, 12, 32) | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stcmy(Register r1, int64_t m3, int64_t d2, Register b2) { emit_48( STCMY_ZOPC | regt(r1, 8, 48) | uimm4(m3, 12, 48) | simm20(d2)         | regz(b2, 16, 48)); }
+inline void Assembler::z_stcmh(Register r1, int64_t m3, int64_t d2, Register b2) { emit_48( STCMH_ZOPC | regt(r1, 8, 48) | uimm4(m3, 12, 48) | simm20(d2)         | regz(b2, 16, 48)); }
+
+// memory-immediate instructions (8-bit immediate)
+inline void Assembler::z_cli( int64_t d1, Register b1, int64_t i2) { emit_32( CLI_ZOPC  | uimm12(d1, 20, 32) | regz(b1, 16, 32) | uimm8(i2, 8, 32)); }
+inline void Assembler::z_mvi( int64_t d1, Register b1, int64_t i2) { emit_32( MVI_ZOPC  | uimm12(d1, 20, 32) | regz(b1, 16, 32) | imm8(i2, 8, 32)); }
+inline void Assembler::z_tm(  int64_t d1, Register b1, int64_t i2) { emit_32( TM_ZOPC   | uimm12(d1, 20, 32) | regz(b1, 16, 32) | imm8(i2, 8, 32)); }
+inline void Assembler::z_ni(  int64_t d1, Register b1, int64_t i2) { emit_32( NI_ZOPC   | uimm12(d1, 20, 32) | regz(b1, 16, 32) | imm8(i2, 8, 32)); }
+inline void Assembler::z_oi(  int64_t d1, Register b1, int64_t i2) { emit_32( OI_ZOPC   | uimm12(d1, 20, 32) | regz(b1, 16, 32) | imm8(i2, 8, 32)); }
+inline void Assembler::z_xi(  int64_t d1, Register b1, int64_t i2) { emit_32( XI_ZOPC   | uimm12(d1, 20, 32) | regz(b1, 16, 32) | imm8(i2, 8, 32)); }
+inline void Assembler::z_cliy(int64_t d1, Register b1, int64_t i2) { emit_48( CLIY_ZOPC | simm20(d1)         | regz(b1, 16, 48) | uimm8(i2, 8, 48)); }
+inline void Assembler::z_mviy(int64_t d1, Register b1, int64_t i2) { emit_48( MVIY_ZOPC | simm20(d1)         | regz(b1, 16, 48) | imm8(i2, 8, 48)); }
+inline void Assembler::z_tmy( int64_t d1, Register b1, int64_t i2) { emit_48( TMY_ZOPC  | simm20(d1)         | regz(b1, 16, 48) | imm8(i2, 8, 48)); }
+inline void Assembler::z_niy( int64_t d1, Register b1, int64_t i2) { emit_48( NIY_ZOPC  | simm20(d1)         | regz(b1, 16, 48) | imm8(i2, 8, 48)); }
+inline void Assembler::z_oiy( int64_t d1, Register b1, int64_t i2) { emit_48( OIY_ZOPC  | simm20(d1)         | regz(b1, 16, 48) | imm8(i2, 8, 48)); }
+inline void Assembler::z_xiy( int64_t d1, Register b1, int64_t i2) { emit_48( XIY_ZOPC  | simm20(d1)         | regz(b1, 16, 48) | imm8(i2, 8, 48)); }
+
+inline void Assembler::z_cli( const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLI");  z_cli( a.disp12(), a.base(), imm); }
+inline void Assembler::z_mvi( const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLI");  z_mvi( a.disp12(), a.base(), imm); }
+inline void Assembler::z_tm(  const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLI");  z_tm(  a.disp12(), a.base(), imm); }
+inline void Assembler::z_ni(  const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLI");  z_ni(  a.disp12(), a.base(), imm); }
+inline void Assembler::z_oi(  const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLI");  z_oi(  a.disp12(), a.base(), imm); }
+inline void Assembler::z_xi(  const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLI");  z_xi(  a.disp12(), a.base(), imm); }
+inline void Assembler::z_cliy(const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in CLIY"); z_cliy(a.disp20(), a.base(), imm); }
+inline void Assembler::z_mviy(const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in MVIY"); z_mviy(a.disp20(), a.base(), imm); }
+inline void Assembler::z_tmy( const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in TMY");  z_tmy( a.disp20(), a.base(), imm); }
+inline void Assembler::z_niy( const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in NIY");  z_niy( a.disp20(), a.base(), imm); }
+inline void Assembler::z_oiy( const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in OIY");  z_oiy( a.disp20(), a.base(), imm); }
+inline void Assembler::z_xiy( const Address& a, int64_t imm) { assert(!a.has_index(), " no index reg allowed in XIY");  z_xiy( a.disp20(), a.base(), imm); }
+
+
+inline void Assembler::z_mvc(const Address& d, const Address& s, int64_t l) {
+  assert(!d.has_index() && !s.has_index(), "Address operand can not be encoded.");
+  z_mvc(d.disp(), l-1, d.base(), s.disp(), s.base());
+}
+inline void Assembler::z_mvc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2) { emit_48( MVC_ZOPC | uimm12(d1, 20, 48) | uimm8(l, 8, 48) | regz(b1, 16, 48) | uimm12(d2, 36, 48) | regz(b2, 32, 48)); }
+inline void Assembler::z_mvcle(Register r1, Register r3, int64_t d2, Register b2) { emit_32( MVCLE_ZOPC | reg(r1, 8, 32) | reg(r3, 12, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+
+inline void Assembler::z_mvhhi( int64_t d1, Register b1, int64_t i2) { emit_48( MVHHI_ZOPC | uimm12( d1, 20, 48) | regz(b1, 16, 48) | simm16(i2, 32, 48)); }
+inline void Assembler::z_mvhi ( int64_t d1, Register b1, int64_t i2) { emit_48( MVHI_ZOPC  | uimm12( d1, 20, 48) | regz(b1, 16, 48) | simm16(i2, 32, 48)); }
+inline void Assembler::z_mvghi( int64_t d1, Register b1, int64_t i2) { emit_48( MVGHI_ZOPC | uimm12( d1, 20, 48) | regz(b1, 16, 48) | simm16(i2, 32, 48)); }
+inline void Assembler::z_mvhhi( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVHHI"); z_mvghi( d.disp(), d.baseOrR0(), i2); }
+inline void Assembler::z_mvhi ( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVHI");  z_mvghi( d.disp(), d.baseOrR0(), i2); }
+inline void Assembler::z_mvghi( const Address &d, int64_t i2) { assert(!d.has_index(), " no index reg allowed in MVGHI"); z_mvghi( d.disp(), d.baseOrR0(), i2); }
+
+inline void Assembler::z_ex(Register r1, int64_t d2, Register x2, Register b2) { emit_32( EX_ZOPC | regz(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+
+inline void Assembler::z_ic  (Register r1, int64_t d2, Register x2, Register b2) { emit_32( IC_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_icy (Register r1, int64_t d2, Register x2, Register b2) { emit_48( ICY_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_icm (Register r1, int64_t m3, int64_t d2, Register b2) { emit_32( ICM_ZOPC  | regt(r1, 8, 32) | uimm4(m3, 12, 32) | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_icmy(Register r1, int64_t m3, int64_t d2, Register b2) { emit_48( ICMY_ZOPC | regt(r1, 8, 48) | uimm4(m3, 12, 48) | simm20(d2)         | regz(b2, 16, 48)); }
+inline void Assembler::z_icmh(Register r1, int64_t m3, int64_t d2, Register b2) { emit_48( ICMH_ZOPC | regt(r1, 8, 48) | uimm4(m3, 12, 48) | simm20(d2)         | regz(b2, 16, 48)); }
+inline void Assembler::z_iihh(Register r1, int64_t i2) { emit_32( IIHH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_iihl(Register r1, int64_t i2) { emit_32( IIHL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_iilh(Register r1, int64_t i2) { emit_32( IILH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_iill(Register r1, int64_t i2) { emit_32( IILL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_iihf(Register r1, int64_t i2) { emit_48( IIHF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_iilf(Register r1, int64_t i2) { emit_48( IILF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_lgf(Register r1, const Address& a) { z_lgf(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lgf(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LGF_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_lhy(Register r1, const Address &a) { z_lhy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lhy(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LHY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_lgh(Register r1, const Address &a) { z_lgh(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lgh(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LGH_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_lt(Register r1, const Address &a) { z_lt(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lt (Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LT_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ltg(Register r1, const Address &a) { z_ltg(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ltg(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LTG_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ltgf(Register r1, const Address &a) { z_ltgf(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ltgf(Register r1, int64_t d2, Register x2, Register b2) { emit_48( LTGF_ZOPC| regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_lb(Register r1, const Address &a) { z_lb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lb (Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LB_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_lgb(Register r1, const Address &a) { z_lgb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_lgb(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LGB_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ly(Register r1, const Address &a) { z_ly(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ly(Register r1, int64_t d2, Register x2, Register b2)   { emit_48( LY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_llc(Register r1, const Address& a) { z_llc(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_llc(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LLC_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_llh(Register r1, const Address &a) { z_llh(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_llh(Register r1, int64_t d2, Register x2, Register b2)  { emit_48( LLH_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_llgf(Register r1, const Address &a) { z_llgf(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_llgf(Register r1, int64_t d2, Register x2, Register b2) { emit_48( LLGF_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_llgh(Register r1, const Address &a) { z_llgh(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_llgh(Register r1, int64_t d2, Register x2, Register b2) { emit_48( LLGH_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_llgc(Register r1, const Address &a) { z_llgc(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_llgc(Register r1, int64_t d2, Register x2, Register b2) { emit_48( LLGC_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_llgc(Register r1, int64_t d2, Register b2)              { z_llgc( r1, d2, Z_R0, b2); }
+inline void Assembler::z_lhi(Register r1, int64_t i2) { emit_32( LHI_ZOPC | regt(r1, 8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_lghi(Register r1, int64_t i2) { emit_32( LGHI_ZOPC | regt(r1, 8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_lgfi(Register r1, int64_t i2) { emit_48( LGFI_ZOPC | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_llihf(Register r1, int64_t i2) { emit_48( LLIHF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_llilf(Register r1, int64_t i2) { emit_48( LLILF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_llihh(Register r1, int64_t i2) { emit_32( LLIHH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_llihl(Register r1, int64_t i2) { emit_32( LLIHL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_llilh(Register r1, int64_t i2) { emit_32( LLILH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_llill(Register r1, int64_t i2) { emit_32( LLILL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+
+// allow "monadic" use
+inline void Assembler::z_lcr(  Register r1, Register r2) { emit_16( LCR_ZOPC   | regt( r1,  8, 16) | reg((r2 == noreg) ? r1:r2, 12, 16)); }
+inline void Assembler::z_lcgr( Register r1, Register r2) { emit_32( LCGR_ZOPC  | regt( r1, 24, 32) | reg((r2 == noreg) ? r1:r2, 28, 32)); }
+inline void Assembler::z_lcgfr(Register r1, Register r2) { emit_32( LCGFR_ZOPC | regt( r1, 24, 32) | reg((r2 == noreg) ? r1:r2, 28, 32)); }
+inline void Assembler::z_lnr(  Register r1, Register r2) { emit_16( LNR_ZOPC   | regt( r1,  8, 16) | reg((r2 == noreg) ? r1:r2, 12, 16)); }
+inline void Assembler::z_lngr( Register r1, Register r2) { emit_32( LNGR_ZOPC  | regt( r1, 24, 32) | reg((r2 == noreg) ? r1:r2, 28, 32)); }
+inline void Assembler::z_lngfr(Register r1, Register r2) { emit_32( LNGFR_ZOPC | regt( r1, 24, 32) | reg((r2 == noreg) ? r1:r2, 28, 32)); }
+
+inline void Assembler::z_lrvr( Register r1, Register r2) { emit_32( LRVR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_lrvgr(Register r1, Register r2) { emit_32( LRVGR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+inline void Assembler::z_ltr(  Register r1, Register r2) { emit_16( LTR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_ltgr( Register r1, Register r2) { emit_32( LTGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_ltgfr(Register r1, Register r2) { emit_32( LTGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_stc(  Register r1, const Address &a) { z_stc(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_stc(  Register r1, int64_t d2, Register x2, Register b2) { emit_32( STC_ZOPC | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stcy( Register r1, const Address &a) { z_stcy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_stcy( Register r1, int64_t d2, Register x2, Register b2) { emit_48( STCY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_sthy( Register r1, const Address &a) { z_sthy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sthy( Register r1, int64_t d2, Register x2, Register b2) { emit_48( STHY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_sty(  Register r1, const Address &a) { z_sty(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sty(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( STY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_stfle(int64_t d2, Register b2) { emit_32(STFLE_ZOPC | uimm12(d2,20,32) | regz(b2,16,32)); }
+
+
+//-----------------------------------
+// SHIFT/RORATE OPERATIONS
+//-----------------------------------
+inline void Assembler::z_sla( Register r1,              int64_t d2, Register b2) { emit_32( SLA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_slag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
+inline void Assembler::z_sra( Register r1,              int64_t d2, Register b2) { emit_32( SRA_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srag(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRAG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
+inline void Assembler::z_sll( Register r1,              int64_t d2, Register b2) { emit_32( SLL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_sllg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SLLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
+inline void Assembler::z_srl( Register r1,              int64_t d2, Register b2) { emit_32( SRL_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_srlg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( SRLG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(b2, 16, 48) | reg(r3, 12, 48)); }
+
+// rotate left
+inline void Assembler::z_rll( Register r1, Register r3, int64_t d2, Register b2) { emit_48( RLL_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | reg(b2, 16, 48)); }
+inline void Assembler::z_rllg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( RLLG_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | simm20(d2) | reg(b2, 16, 48)); }
+
+// Rotate the AND/XOR/OR/insert
+inline void Assembler::z_rnsbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only) { // Rotate then AND selected bits.  -- z196
+  const int64_t len = 48;
+  assert(Immediate::is_uimm(spos3, 6), "range start out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(epos4, 6), "range end   out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(nrot5, 6), "rotate amount out of range"); // Could just leave it as is. leftmost 2 bits are ignored by instruction.
+  emit_48( RNSBG_ZOPC | regt(r1, 8, len) | regt(r2, 12, len) | uimm6(spos3, 16+2, len) | uimm6(epos4, 24+2, len) | uimm6(nrot5, 32+2, len) | u_field(test_only ? 1 : 0, len-16-1, len-16-1));
+}
+inline void Assembler::z_rxsbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only) { // Rotate then XOR selected bits.  -- z196
+  const int64_t len = 48;
+  assert(Immediate::is_uimm(spos3, 6), "range start out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(epos4, 6), "range end   out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(nrot5, 6), "rotate amount out of range"); // Could just leave it as is. leftmost 2 bits are ignored by instruction.
+  emit_48( RXSBG_ZOPC | regt(r1, 8, len) | regt(r2, 12, len) | uimm6(spos3, 16+2, len) | uimm6(epos4, 24+2, len) | uimm6(nrot5, 32+2, len) | u_field(test_only ? 1 : 0, len-16-1, len-16-1));
+}
+inline void Assembler::z_rosbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only) { // Rotate then OR selected bits.  -- z196
+  const int64_t len = 48;
+  assert(Immediate::is_uimm(spos3, 6), "range start out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(epos4, 6), "range end   out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(nrot5, 6), "rotate amount out of range"); // Could just leave it as is. leftmost 2 bits are ignored by instruction.
+  emit_48( ROSBG_ZOPC | regt(r1, 8, len) | regt(r2, 12, len) | uimm6(spos3, 16+2, len) | uimm6(epos4, 24+2, len) | uimm6(nrot5, 32+2, len) | u_field(test_only ? 1 : 0, len-16-1, len-16-1));
+}
+inline void Assembler::z_risbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool zero_rest) { // Rotate then INS selected bits.  -- z196
+  const int64_t len = 48;
+  assert(Immediate::is_uimm(spos3, 6), "range start out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(epos4, 6), "range end   out of range");   // Could just trim to 6bits wide w/o assertion.
+  assert(Immediate::is_uimm(nrot5, 6), "rotate amount out of range"); // Could just leave it as is. leftmost 2 bits are ignored by instruction.
+  emit_48( RISBG_ZOPC | regt(r1, 8, len) | regt(r2, 12, len) | uimm6(spos3, 16+2, len) | uimm6(epos4, 24+2, len) | uimm6(nrot5, 32+2, len) | u_field(zero_rest ? 1 : 0, len-24-1, len-24-1));
+}
+
+
+//------------------------------
+// LOGICAL OPERATIONS
+//------------------------------
+inline void Assembler::z_n(   Register r1, int64_t d2, Register x2, Register b2) { emit_32( N_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_ny(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( NY_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ng(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( NG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_n(   Register r1, const Address& a) { z_n( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ny(  Register r1, const Address& a) { z_ny(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ng(  Register r1, const Address& a) { z_ng(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_nr(  Register r1, Register r2)              { emit_16( NR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_ngr( Register r1, Register r2)              { emit_32( NGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_nrk( Register r1, Register r2, Register r3) { emit_32( NRK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_ngrk(Register r1, Register r2, Register r3) { emit_32( NGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+
+inline void Assembler::z_nihh(Register r1, int64_t i2) { emit_32( NIHH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_nihl(Register r1, int64_t i2) { emit_32( NIHL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_nilh(Register r1, int64_t i2) { emit_32( NILH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_nill(Register r1, int64_t i2) { emit_32( NILL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_nihf(Register r1, int64_t i2) { emit_48( NIHF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_nilf(Register r1, int64_t i2) { emit_48( NILF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+
+inline void Assembler::z_o(   Register r1, int64_t d2, Register x2, Register b2) { emit_32( O_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_oy(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( OY_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_og(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( OG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_o(   Register r1, const Address& a) { z_o( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_oy(  Register r1, const Address& a) { z_oy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_og(  Register r1, const Address& a) { z_og(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_or(  Register r1, Register r2)              { emit_16( OR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_ogr( Register r1, Register r2)              { emit_32( OGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_ork( Register r1, Register r2, Register r3) { emit_32( ORK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_ogrk(Register r1, Register r2, Register r3) { emit_32( OGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+
+inline void Assembler::z_oihh(Register r1, int64_t i2) { emit_32( OIHH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_oihl(Register r1, int64_t i2) { emit_32( OIHL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_oilh(Register r1, int64_t i2) { emit_32( OILH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_oill(Register r1, int64_t i2) { emit_32( OILL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_oihf(Register r1, int64_t i2) { emit_48( OIHF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_oilf(Register r1, int64_t i2) { emit_48( OILF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+
+inline void Assembler::z_x(   Register r1, int64_t d2, Register x2, Register b2) { emit_32( X_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_xy(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( XY_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_xg(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( XG_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_x(   Register r1, const Address& a) { z_x( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_xy(  Register r1, const Address& a) { z_xy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_xg(  Register r1, const Address& a) { z_xg(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_xr(  Register r1, Register r2)              { emit_16( XR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_xgr( Register r1, Register r2)              { emit_32( XGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_xrk( Register r1, Register r2, Register r3) { emit_32( XRK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_xgrk(Register r1, Register r2, Register r3) { emit_32( XGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+
+inline void Assembler::z_xihf(Register r1, int64_t i2) { emit_48( XIHF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+inline void Assembler::z_xilf(Register r1, int64_t i2) { emit_48( XILF_ZOPC | regt(r1, 8, 48) | imm32(i2, 16, 48)); }
+
+inline void Assembler::z_nc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2) { emit_48( NC_ZOPC | uimm12(d1, 20, 48) | uimm8(l, 8, 48) | regz(b1, 16, 48) | uimm12(d2, 36, 48) | regz(b2, 32, 48)); }
+inline void Assembler::z_oc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2) { emit_48( OC_ZOPC | uimm12(d1, 20, 48) | uimm8(l, 8, 48) | regz(b1, 16, 48) | uimm12(d2, 36, 48) | regz(b2, 32, 48)); }
+inline void Assembler::z_xc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2) { emit_48( XC_ZOPC | uimm12(d1, 20, 48) | uimm8(l, 8, 48) | regz(b1, 16, 48) | uimm12(d2, 36, 48) | regz(b2, 32, 48)); }
+inline void Assembler::z_nc(Address dst, int64_t len, Address src2) { assert(!dst.has_index() && !src2.has_index(), "Cannot encode index"); z_nc(dst.disp12(), len-1, dst.base(), src2.disp12(), src2.base()); }
+inline void Assembler::z_oc(Address dst, int64_t len, Address src2) { assert(!dst.has_index() && !src2.has_index(), "Cannot encode index"); z_oc(dst.disp12(), len-1, dst.base(), src2.disp12(), src2.base()); }
+inline void Assembler::z_xc(Address dst, int64_t len, Address src2) { assert(!dst.has_index() && !src2.has_index(), "Cannot encode index"); z_xc(dst.disp12(), len-1, dst.base(), src2.disp12(), src2.base()); }
+
+
+//---------------
+// ADD
+//---------------
+inline void Assembler::z_a(   Register r1, int64_t d2, Register x2, Register b2) { emit_32( A_ZOPC    | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_ay(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( AY_ZOPC   | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_al(  Register r1, int64_t d2, Register x2, Register b2) { emit_32( AL_ZOPC   | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_aly( Register r1, int64_t d2, Register x2, Register b2) { emit_48( ALY_ZOPC  | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ag(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( AG_ZOPC   | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_agf( Register r1, int64_t d2, Register x2, Register b2) { emit_48( AGF_ZOPC  | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_alg( Register r1, int64_t d2, Register x2, Register b2) { emit_48( ALG_ZOPC  | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_algf(Register r1, int64_t d2, Register x2, Register b2) { emit_48( ALGF_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_a(   Register r1, const Address& a) { z_a(   r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ay(  Register r1, const Address& a) { z_ay(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_al(  Register r1, const Address& a) { z_al(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_aly( Register r1, const Address& a) { z_aly( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ag(  Register r1, const Address& a) { z_ag(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_agf( Register r1, const Address& a) { z_agf( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_alg( Register r1, const Address& a) { z_alg( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_algf(Register r1, const Address& a) { z_algf(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_ar(  Register r1, Register r2) { emit_16( AR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_agr( Register r1, Register r2) { emit_32( AGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_agfr(Register r1, Register r2) { emit_32( AGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_ark( Register r1, Register r2, Register r3) { emit_32( ARK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_agrk(Register r1, Register r2, Register r3) { emit_32( AGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+
+inline void Assembler::z_ahi(  Register r1, int64_t i2) { emit_32( AHI_ZOPC  | regt(r1, 8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_afi(  Register r1, int64_t i2) { emit_48( AFI_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_aghi( Register r1, int64_t i2) { emit_32( AGHI_ZOPC | regt(r1, 8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_agfi( Register r1, int64_t i2) { emit_48( AGFI_ZOPC | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_aih(  Register r1, int64_t i2) { emit_48( AIH_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_ahik( Register r1, Register r3, int64_t i2) { emit_48( AHIK_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm16(i2, 16, 48)); }
+inline void Assembler::z_aghik(Register r1, Register r3, int64_t i2) { emit_48( AGHIK_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | simm16(i2, 16, 48)); }
+
+
+//-----------------------
+// ADD LOGICAL
+//-----------------------
+inline void Assembler::z_alr(  Register r1, Register r2) { emit_16( ALR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_algr( Register r1, Register r2) { emit_32( ALGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_algfr(Register r1, Register r2) { emit_32( ALGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_alrk( Register r1, Register r2, Register r3) { emit_32( ALRK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_algrk(Register r1, Register r2, Register r3) { emit_32( ALGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_alcgr(Register r1, Register r2) { emit_32( ALCGR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+inline void Assembler::z_alfi( Register r1, int64_t i2) { emit_48( ALFI_ZOPC |  regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+inline void Assembler::z_algfi(Register r1, int64_t i2) { emit_48( ALGFI_ZOPC | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+
+inline void Assembler::z_alhsik( Register r1, Register r3, int64_t i2) { emit_48( ALHSIK_ZOPC  | regt(r1, 8, 48) | reg(r3, 12, 48) | simm16(i2, 16, 48)); }
+inline void Assembler::z_alghsik(Register r1, Register r3, int64_t i2) { emit_48( ALGHSIK_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | simm16(i2, 16, 48)); }
+
+// In-memory arithmetic (add signed, add logical with signed immediate)
+inline void Assembler::z_asi(  int64_t d1, Register b1, int64_t i2) { emit_48( ASI_ZOPC   | simm8(i2, 8, 48) | simm20(d1) | regz(b1, 16, 48)); }
+inline void Assembler::z_agsi( int64_t d1, Register b1, int64_t i2) { emit_48( AGSI_ZOPC  | simm8(i2, 8, 48) | simm20(d1) | regz(b1, 16, 48)); }
+inline void Assembler::z_alsi( int64_t d1, Register b1, int64_t i2) { emit_48( ALSI_ZOPC  | simm8(i2, 8, 48) | simm20(d1) | regz(b1, 16, 48)); }
+inline void Assembler::z_algsi(int64_t d1, Register b1, int64_t i2) { emit_48( ALGSI_ZOPC | simm8(i2, 8, 48) | simm20(d1) | regz(b1, 16, 48)); }
+inline void Assembler::z_asi(  const Address& d, int64_t i2) { assert(!d.has_index(), "No index in ASI");   z_asi(  d.disp(), d.base(), i2); }
+inline void Assembler::z_agsi( const Address& d, int64_t i2) { assert(!d.has_index(), "No index in AGSI");  z_agsi( d.disp(), d.base(), i2); }
+inline void Assembler::z_alsi( const Address& d, int64_t i2) { assert(!d.has_index(), "No index in ALSI");  z_alsi( d.disp(), d.base(), i2); }
+inline void Assembler::z_algsi(const Address& d, int64_t i2) { assert(!d.has_index(), "No index in ALGSI"); z_algsi(d.disp(), d.base(), i2); }
+
+
+//--------------------
+// SUBTRACT
+//--------------------
+inline void Assembler::z_s(   Register r1, int64_t d2, Register x2, Register b2) { emit_32( S_ZOPC    | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_sy(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( SY_ZOPC   | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_sg(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( SG_ZOPC   | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_sgf( Register r1, int64_t d2, Register x2, Register b2) { emit_48( SGF_ZOPC  | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_slg( Register r1, int64_t d2, Register x2, Register b2) { emit_48( SLG_ZOPC  | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_slgf(Register r1, int64_t d2, Register x2, Register b2) { emit_48( SLGF_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_s(   Register r1, const Address& a) { z_s(   r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sy(  Register r1, const Address& a) { z_sy(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sg(  Register r1, const Address& a) { z_sg(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sgf( Register r1, const Address& a) { z_sgf( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_slg( Register r1, const Address& a) { z_slg( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_slgf(Register r1, const Address& a) { z_slgf(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_sr(  Register r1, Register r2) { emit_16( SR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_sgr( Register r1, Register r2) { emit_32( SGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_sgfr(Register r1, Register r2) { emit_32( SGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_srk( Register r1, Register r2, Register r3) { emit_32( SRK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_sgrk(Register r1, Register r2, Register r3) { emit_32( SGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+
+inline void Assembler::z_sh(  Register r1, int64_t d2, Register x2, Register b2) { emit_32( SH_ZOPC  | regt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_shy( Register r1, int64_t d2, Register x2, Register b2) { emit_48( SHY_ZOPC | regt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_sh(  Register r1, const Address &a) { z_sh( r1, a.disp(), a.indexOrR0(), a.base()); }
+inline void Assembler::z_shy( Register r1, const Address &a) { z_shy(r1, a.disp(), a.indexOrR0(), a.base()); }
+
+
+//----------------------------
+// SUBTRACT LOGICAL
+//----------------------------
+inline void Assembler::z_slr(  Register r1, Register r2) { emit_16( SLR_ZOPC   | regt(r1,  8, 16) | reg(r2, 12, 16)); }
+inline void Assembler::z_slgr( Register r1, Register r2) { emit_32( SLGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_slgfr(Register r1, Register r2) { emit_32( SLGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_slrk( Register r1, Register r2, Register r3) { emit_32(SLRK_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_slgrk(Register r1, Register r2, Register r3) { emit_32(SLGRK_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32) | reg(r3, 16, 32)); }
+inline void Assembler::z_slfi( Register r1, int64_t i2) { emit_48( SLFI_ZOPC  | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+inline void Assembler::z_slgfi(Register r1, int64_t i2) { emit_48( SLGFI_ZOPC | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+
+
+//--------------------
+// MULTIPLY
+//--------------------
+inline void Assembler::z_msr(  Register r1, Register r2) { emit_32( MSR_ZOPC   | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_msgr( Register r1, Register r2) { emit_32( MSGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_msgfr(Register r1, Register r2) { emit_32( MSGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_mlr(  Register r1, Register r2) { emit_32( MLR_ZOPC   | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_mlgr( Register r1, Register r2) { emit_32( MLGR_ZOPC  | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+inline void Assembler::z_mhy( Register r1, int64_t d2, Register x2, Register b2) { emit_48( MHY_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_msy( Register r1, int64_t d2, Register x2, Register b2) { emit_48( MSY_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_msg( Register r1, int64_t d2, Register x2, Register b2) { emit_48( MSG_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_msgf(Register r1, int64_t d2, Register x2, Register b2) { emit_48( MSGF_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ml(  Register r1, int64_t d2, Register x2, Register b2) { emit_48( ML_ZOPC   | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_mlg( Register r1, int64_t d2, Register x2, Register b2) { emit_48( MLG_ZOPC  | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+
+inline void Assembler::z_mhy( Register r1, const Address& a) { z_mhy( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_msy( Register r1, const Address& a) { z_msy( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_msg( Register r1, const Address& a) { z_msg( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_msgf(Register r1, const Address& a) { z_msgf(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ml(  Register r1, const Address& a) { z_ml(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_mlg( Register r1, const Address& a) { z_mlg( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_msfi( Register r1, int64_t i2) { emit_48( MSFI_ZOPC  | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_msgfi(Register r1, int64_t i2) { emit_48( MSGFI_ZOPC | regt(r1, 8, 48) | simm32(i2, 16, 48)); }
+inline void Assembler::z_mhi(  Register r1, int64_t i2) { emit_32( MHI_ZOPC   | regt(r1, 8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_mghi( Register r1, int64_t i2) { emit_32( MGHI_ZOPC  | regt(r1, 8, 32) | simm16(i2, 16, 32)); }
+
+
+//------------------
+// DIVIDE
+//------------------
+inline void Assembler::z_dsgr( Register r1, Register r2) { emit_32( DSGR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_dsgfr(Register r1, Register r2) { emit_32( DSGFR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+
+//-------------------
+// COMPARE
+//-------------------
+inline void Assembler::z_cr(  Register r1, Register r2) { emit_16( CR_ZOPC   | reg(r1,  8, 16) | reg(r2,12,16)); }
+inline void Assembler::z_cgr( Register r1, Register r2) { emit_32( CGR_ZOPC  | reg(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_cgfr(Register r1, Register r2) { emit_32( CGFR_ZOPC | reg(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_chi( Register r1, int64_t i2)  { emit_32( CHI_ZOPC  | reg(r1,  8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_cghi(Register r1, int64_t i2)  { emit_32( CGHI_ZOPC | reg(r1,  8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_cfi( Register r1, int64_t i2)  { emit_48( CFI_ZOPC  | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+inline void Assembler::z_cgfi(Register r1, int64_t i2)  { emit_48( CGFI_ZOPC | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+inline void Assembler::z_ch(Register r1, const Address &a) { z_ch(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ch(Register r1, int64_t d2, Register x2, Register b2) { emit_32( CH_ZOPC | reg(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_c(Register r1, const Address &a) { z_c(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_c(Register r1,  int64_t d2, Register x2, Register b2) { emit_32( C_ZOPC  | reg(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_cy(Register r1, const Address &a) { z_cy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_cy(Register r1, int64_t d2, Register x2, Register b2) { emit_48( CY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_cy(Register r1, int64_t d2, Register b2) { z_cy(r1, d2, Z_R0, b2); }
+inline void Assembler::z_cg(Register r1, const Address &a) { z_cg(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_cg(Register r1, int64_t d2, Register x2, Register b2) { emit_48( CG_ZOPC | reg(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_clr(Register r1, Register r2) { emit_16( CLR_ZOPC | reg(r1,8,16) | reg(r2,12,16)); }
+inline void Assembler::z_clgr(Register r1, Register r2) { emit_32( CLGR_ZOPC | regt(r1, 24, 32) | reg(r2, 28, 32)); }
+
+
+inline void Assembler::z_clfi(Register r1, int64_t i2)  { emit_48( CLFI_ZOPC  | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+inline void Assembler::z_clgfi(Register r1, int64_t i2) { emit_48( CLGFI_ZOPC | regt(r1, 8, 48) | uimm32(i2, 16, 48)); }
+inline void Assembler::z_cl(Register r1, const Address &a) { z_cl(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_cl(Register r1, int64_t d2, Register x2, Register b2) { emit_32( CL_ZOPC | regt(r1, 8, 32) | uimm12(d2,20,32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_cly(Register r1, const Address &a) { z_cly(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_cly(Register r1, int64_t d2, Register x2, Register b2) { emit_48( CLY_ZOPC | regt(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_cly(Register r1, int64_t d2, Register b2) { z_cly(r1, d2, Z_R0, b2); }
+inline void Assembler::z_clg(Register r1, const Address &a) { z_clg(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_clg(Register r1, int64_t d2, Register x2, Register b2) { emit_48( CLG_ZOPC | reg(r1, 8, 48) | simm20(d2) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_clc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2) { emit_48( CLC_ZOPC | uimm12(d1, 20, 48) | uimm8(l, 8, 48) | regz(b1, 16, 48) | uimm12(d2, 36, 48) | regz(b2, 32, 48)); }
+inline void Assembler::z_clcle(Register r1, Register r3, int64_t d2, Register b2) { emit_32( CLCLE_ZOPC | reg(r1, 8, 32) | reg(r3, 12, 32) | uimm12(d2, 20, 32) | reg(b2, 16, 32)); }
+inline void Assembler::z_clclu(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CLCLU_ZOPC | reg(r1, 8, 48) | reg(r3, 12, 48) | uimm12(d2, 20, 48) | reg(b2, 16, 48)); }
+
+inline void Assembler::z_tmll(Register r1, int64_t i2) { emit_32( TMLL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_tmlh(Register r1, int64_t i2) { emit_32( TMLH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_tmhl(Register r1, int64_t i2) { emit_32( TMHL_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+inline void Assembler::z_tmhh(Register r1, int64_t i2) { emit_32( TMHH_ZOPC | regt(r1, 8, 32) | imm16(i2, 16, 32)); }
+
+// translate characters
+inline void Assembler::z_troo(Register r1, Register r2, int64_t m3) { emit_32( TROO_ZOPC | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_trot(Register r1, Register r2, int64_t m3) { emit_32( TROT_ZOPC | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_trto(Register r1, Register r2, int64_t m3) { emit_32( TRTO_ZOPC | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_trtt(Register r1, Register r2, int64_t m3) { emit_32( TRTT_ZOPC | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+
+// signed comparison
+inline void Assembler::z_crb(Register r1,  Register r2, branch_condition m3, int64_t d4, Register b4) { emit_48( CRB_ZOPC  | reg(r1, 8, 48) | reg(r2, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_cgrb(Register r1, Register r2, branch_condition m3, int64_t d4, Register b4) { emit_48( CGRB_ZOPC | reg(r1, 8, 48) | reg(r2, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_crj(Register r1,  Register r2, branch_condition m3, address a4)              { emit_48( CRJ_ZOPC  | reg(r1, 8, 48) | reg(r2, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_cgrj(Register r1, Register r2, branch_condition m3, address a4)              { emit_48( CGRJ_ZOPC | reg(r1, 8, 48) | reg(r2, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_cib(Register r1,  int64_t i2, branch_condition m3, int64_t d4, Register b4)  { emit_48( CIB_ZOPC  | reg(r1, 8, 48) | uimm4(m3, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | simm8(i2, 32, 48)); }
+inline void Assembler::z_cgib(Register r1, int64_t i2, branch_condition m3, int64_t d4, Register b4)  { emit_48( CGIB_ZOPC | reg(r1, 8, 48) | uimm4(m3, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | simm8(i2, 32, 48)); }
+inline void Assembler::z_cij(Register r1,  int64_t i2, branch_condition m3, address a4)               { emit_48( CIJ_ZOPC  | reg(r1, 8, 48) | uimm4(m3, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | simm8(i2, 32, 48)); }
+inline void Assembler::z_cgij(Register r1, int64_t i2, branch_condition m3, address a4)               { emit_48( CGIJ_ZOPC | reg(r1, 8, 48) | uimm4(m3, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | simm8(i2, 32, 48)); }
+// unsigned comparison
+inline void Assembler::z_clrb(Register r1,  Register r2, branch_condition m3, int64_t d4, Register b4) { emit_48( CLRB_ZOPC  | reg(r1, 8, 48) | reg(r2, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_clgrb(Register r1, Register r2, branch_condition m3, int64_t d4, Register b4) { emit_48( CLGRB_ZOPC | reg(r1, 8, 48) | reg(r2, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_clrj(Register r1,  Register r2, branch_condition m3, address a4)              { emit_48( CLRJ_ZOPC  | reg(r1, 8, 48) | reg(r2, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_clgrj(Register r1, Register r2, branch_condition m3, address a4)              { emit_48( CLGRJ_ZOPC | reg(r1, 8, 48) | reg(r2, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_clib(Register r1,  int64_t i2, branch_condition m3, int64_t d4, Register b4)  { emit_48( CLIB_ZOPC  | reg(r1, 8, 48) | uimm4(m3, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | uimm8(i2, 32, 48)); }
+inline void Assembler::z_clgib(Register r1, int64_t i2, branch_condition m3, int64_t d4, Register b4)  { emit_48( CLGIB_ZOPC | reg(r1, 8, 48) | uimm4(m3, 12, 48) | uimm12(d4, 20, 48) | reg(b4, 16, 48) | uimm8(i2, 32, 48)); }
+inline void Assembler::z_clij(Register r1,  int64_t i2, branch_condition m3, address a4)               { emit_48( CLIJ_ZOPC  | reg(r1, 8, 48) | uimm4(m3, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | uimm8(i2, 32, 48)); }
+inline void Assembler::z_clgij(Register r1, int64_t i2, branch_condition m3, address a4)               { emit_48( CLGIJ_ZOPC | reg(r1, 8, 48) | uimm4(m3, 12, 48) | simm16(RelAddr::pcrel_off16(a4, pc()), 16, 48) | uimm8(i2, 32, 48)); }
+
+// Compare and trap instructions (signed).
+inline void Assembler::z_crt(Register  r1, Register r2, int64_t m3)  { emit_32( CRT_ZOPC   | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_cgrt(Register r1, Register r2, int64_t m3)  { emit_32( CGRT_ZOPC  | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_cit(Register  r1, int64_t i2, int64_t m3)   { emit_48( CIT_ZOPC   | reg(r1,  8, 48) | simm16(i2, 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_cgit(Register r1, int64_t i2, int64_t m3)   { emit_48( CGIT_ZOPC  | reg(r1,  8, 48) | simm16(i2, 16, 48) | uimm4(m3, 32, 48)); }
+
+// Compare and trap instructions (unsigned).
+inline void Assembler::z_clrt(Register  r1, Register r2, int64_t m3) { emit_32( CLRT_ZOPC  | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_clgrt(Register r1, Register r2, int64_t m3) { emit_32( CLGRT_ZOPC | reg(r1, 24, 32) | reg(r2, 28, 32) | uimm4(m3, 16, 32)); }
+inline void Assembler::z_clfit(Register r1, int64_t i2, int64_t m3)  { emit_48( CLFIT_ZOPC | reg(r1,  8, 48) | uimm16(i2, 16, 48) | uimm4(m3, 32, 48)); }
+inline void Assembler::z_clgit(Register r1, int64_t i2, int64_t m3)  { emit_48( CLGIT_ZOPC | reg(r1,  8, 48) | uimm16(i2, 16, 48) | uimm4(m3, 32, 48)); }
+
+inline void Assembler::z_bc(  branch_condition m1, int64_t d2, Register x2, Register b2) { emit_32( BC_ZOPC | 0 << 16 | uimm4(m1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_bcr( branch_condition m1, Register r2) { emit_16( BCR_ZOPC | uimm4(m1,8,16) | reg(r2,12,16)); }
+inline void Assembler::z_brc( branch_condition i1, int64_t i2)  { emit_32( BRC_ZOPC | uimm4(i1, 8, 32) | simm16(i2, 16, 32)); }
+inline void Assembler::z_brc( branch_condition i1, address a)   { emit_32( BRC_ZOPC | uimm4(i1, 8, 32) | simm16(RelAddr::pcrel_off16(a, pc()), 16, 32)); }
+inline void Assembler::z_brcl(branch_condition i1, address a)   { emit_48( BRCL_ZOPC | uimm4(i1, 8, 48)| simm32(RelAddr::pcrel_off32(a, pc()), 16, 48)); }
+inline void Assembler::z_bctgr(Register r1, Register r2)        { emit_32( BCTGR_ZOPC | reg( r1, 24, 32) | reg( r2, 28, 32)); };
+
+inline void Assembler::z_basr(Register r1, Register r2) { emit_16( BASR_ZOPC | regt(r1,8,16) | reg(r2,12,16)); }
+
+inline void Assembler::z_brasl(Register r1, address a) { emit_48( BRASL_ZOPC | regt(r1, 8, 48) | simm32(RelAddr::pcrel_off32(a, pc()), 16, 48)); }
+
+inline void Assembler::z_brct(Register r1, address a) { emit_32( BRCT_ZOPC | regt(r1, 8, 32) | simm16(RelAddr::pcrel_off16(a, pc()), 16, 32)); }
+inline void Assembler::z_brct(Register r1, Label& L) {z_brct(r1, target(L)); }
+
+inline void Assembler::z_brxh(Register r1, Register r3, address a) {emit_32( BRXH_ZOPC | reg(r1, 8, 32) | reg(r3, 12, 32)  | simm16(RelAddr::pcrel_off16(a, pc()), 16, 32));}
+inline void Assembler::z_brxh(Register r1, Register r3, Label& L) {z_brxh(r1, r3, target(L)); }
+
+inline void Assembler::z_brxle(Register r1, Register r3, address a) {emit_32( BRXLE_ZOPC | reg(r1, 8, 32) | reg(r3, 12, 32) | simm16(RelAddr::pcrel_off16(a, pc()), 16, 32));}
+inline void Assembler::z_brxle(Register r1, Register r3, Label& L) {z_brxle(r1, r3, target(L)); }
+
+inline void Assembler::z_brxhg(Register r1, Register r3, address a) {emit_48( BRXHG_ZOPC | reg(r1, 8, 48) | reg(r3, 12, 48) | simm16(RelAddr::pcrel_off16(a, pc()), 16, 48));}
+inline void Assembler::z_brxhg(Register r1, Register r3, Label& L) {z_brxhg(r1, r3, target(L)); }
+
+inline void Assembler::z_brxlg(Register r1, Register r3, address a) {emit_48( BRXLG_ZOPC | reg(r1, 8, 48) | reg(r3, 12, 48) | simm16(RelAddr::pcrel_off16(a, pc()), 16, 48));}
+inline void Assembler::z_brxlg(Register r1, Register r3, Label& L) {z_brxlg(r1, r3, target(L)); }
+
+inline void Assembler::z_flogr(Register r1, Register r2) { emit_32( FLOGR_ZOPC  | reg(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_popcnt(Register r1, Register r2) { emit_32( POPCNT_ZOPC  | reg(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_ahhhr(Register r1, Register r2, Register r3) { emit_32( AHHHR_ZOPC  | reg(r3, 16, 32) | reg(r1, 24, 32) | reg(r2, 28, 32)); }
+inline void Assembler::z_ahhlr(Register r1, Register r2, Register r3) { emit_32( AHHLR_ZOPC  | reg(r3, 16, 32) | reg(r1, 24, 32) | reg(r2, 28, 32)); }
+
+inline void Assembler::z_tam() { emit_16( TAM_ZOPC); }
+inline void Assembler::z_stck(int64_t d2, Register b2)  { emit_32( STCK_ZOPC  | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stckf(int64_t d2, Register b2) { emit_32( STCKF_ZOPC | uimm12(d2, 20, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stmg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( STMG_ZOPC | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
+inline void Assembler::z_lmg(Register r1, Register r3, int64_t d2, Register b2)  { emit_48( LMG_ZOPC  | simm20(d2) | reg(r1, 8, 48) | reg(r3,12,48)| reg(b2,16,48) ); }
+
+inline void Assembler::z_cs(Register r1, Register r3, int64_t d2, Register b2)  { emit_32( CS_ZOPC  | regt(r1, 8, 32) | reg(r3, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
+inline void Assembler::z_csy(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSY_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
+inline void Assembler::z_csg(Register r1, Register r3, int64_t d2, Register b2) { emit_48( CSG_ZOPC | regt(r1, 8, 48) | reg(r3, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
+inline void Assembler::z_cs( Register r1, Register r3, const Address& a) { assert(!a.has_index(), "Cannot encode index"); z_cs( r1, r3, a.disp(), a.baseOrR0()); }
+inline void Assembler::z_csy(Register r1, Register r3, const Address& a) { assert(!a.has_index(), "Cannot encode index"); z_csy(r1, r3, a.disp(), a.baseOrR0()); }
+inline void Assembler::z_csg(Register r1, Register r3, const Address& a) { assert(!a.has_index(), "Cannot encode index"); z_csg(r1, r3, a.disp(), a.baseOrR0()); }
+
+inline void Assembler::z_cvd(Register r1, int64_t d2, Register x2, Register b2)  { emit_32( CVD_ZOPC  | regt(r1, 8, 32) | reg(x2, 12, 32) | reg(b2, 16, 32) | uimm12(d2, 20, 32)); }
+inline void Assembler::z_cvdg(Register r1, int64_t d2, Register x2, Register b2) { emit_48( CVDG_ZOPC | regt(r1, 8, 48) | reg(x2, 12, 48) | reg(b2, 16, 48) | simm20(d2)); }
+
+
+//-------------------------------
+// FLOAT INSTRUCTIONS
+//-------------------------------
+
+//----------------
+// LOAD
+//----------------
+inline void Assembler::z_ler(  FloatRegister r1, FloatRegister r2) { emit_16( LER_ZOPC   | fregt(r1,8,16)    | freg(r2,12,16));   }
+inline void Assembler::z_ldr(  FloatRegister r1, FloatRegister r2) { emit_16( LDR_ZOPC   | fregt(r1,8,16)    | freg(r2,12,16));   }
+inline void Assembler::z_ldebr(FloatRegister r1, FloatRegister r2) { emit_32( LDEBR_ZOPC | fregt(r1, 24, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_ledbr(FloatRegister r1, FloatRegister r2) { emit_32( LEDBR_ZOPC | fregt(r1, 24, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_le( FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_32( LE_ZOPC  | fregt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_ley(FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_48( LEY_ZOPC | fregt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ld( FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_32( LD_ZOPC  | fregt(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_ldy(FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_48( LDY_ZOPC | fregt(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_le( FloatRegister r1, const Address &a) { z_le( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ley(FloatRegister r1, const Address &a) { z_ley(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ld( FloatRegister r1, const Address &a) { z_ld( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ldy(FloatRegister r1, const Address &a) { z_ldy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_lzdr(FloatRegister r1) { emit_32( LZDR_ZOPC | fregt(r1, 24, 32)); }
+inline void Assembler::z_lzer(FloatRegister f1) { emit_32( LZER_ZOPC | fregt(f1, 24, 32)); }
+
+
+//-----------------
+// STORE
+//-----------------
+inline void Assembler::z_ste( FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_32( STE_ZOPC  | freg(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stey(FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_48( STEY_ZOPC | freg(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_std( FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_32( STD_ZOPC  | freg(r1, 8, 32) | uimm12(d2, 20, 32) | reg(x2, 12, 32) | regz(b2, 16, 32)); }
+inline void Assembler::z_stdy(FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_48( STDY_ZOPC | freg(r1, 8, 48) | simm20(d2)         | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ste( FloatRegister r1, const Address &a) { z_ste( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_stey(FloatRegister r1, const Address &a) { z_stey(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_std( FloatRegister r1, const Address &a) { z_std( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_stdy(FloatRegister r1, const Address &a) { z_stdy(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+
+//---------------
+// ADD
+//---------------
+inline void Assembler::z_aebr( FloatRegister f1, FloatRegister f2)                  { emit_32( AEBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_adbr( FloatRegister f1, FloatRegister f2)                  { emit_32( ADBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_aeb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( AEB_ZOPC | fregt( f1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_adb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( ADB_ZOPC | fregt( f1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_aeb(  FloatRegister r1, const Address& a)                   { z_aeb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_adb(  FloatRegister r1, const Address& a)                   { z_adb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+
+//---------------
+// SUB
+//---------------
+inline void Assembler::z_sebr( FloatRegister f1, FloatRegister f2)                  { emit_32( SEBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_sdbr( FloatRegister f1, FloatRegister f2)                  { emit_32( SDBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_seb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( SEB_ZOPC | fregt( f1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_sdb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( SDB_ZOPC | fregt( f1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_seb(  FloatRegister r1, const Address& a)                   { z_seb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_sdb(  FloatRegister r1, const Address& a)                   { z_sdb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+inline void Assembler::z_lcebr(FloatRegister r1, FloatRegister r2)                   { emit_32( LCEBR_ZOPC | fregt(r1, 24, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_lcdbr(FloatRegister r1, FloatRegister r2)                   { emit_32( LCDBR_ZOPC | fregt(r1, 24, 32) | freg(r2, 28, 32)); }
+
+inline void Assembler::z_lpdbr( FloatRegister fr1, FloatRegister fr2) { emit_32( LPDBR_ZOPC | fregt( fr1, 24,32) | freg((fr2 == fnoreg) ? fr1:fr2, 28, 32)); }
+
+
+//---------------
+// MUL
+//---------------
+inline void Assembler::z_meebr(FloatRegister f1, FloatRegister f2)                  { emit_32( MEEBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_mdbr( FloatRegister f1, FloatRegister f2)                  { emit_32( MDBR_ZOPC  | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_meeb( FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( MEEB_ZOPC | fregt( f1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_mdb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( MDB_ZOPC  | fregt( f1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_meeb( FloatRegister r1, const Address& a)                   { z_meeb( r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_mdb(  FloatRegister r1, const Address& a)                   { z_mdb(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+
+//---------------
+// DIV
+//---------------
+inline void Assembler::z_debr( FloatRegister f1, FloatRegister f2)                      { emit_32( DEBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_ddbr( FloatRegister f1, FloatRegister f2)                      { emit_32( DDBR_ZOPC | fregt( f1, 24, 32) | freg( f2, 28, 32));}
+inline void Assembler::z_deb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( DEB_ZOPC  | fregt( f1, 8, 48)  | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_ddb(  FloatRegister f1, int64_t d2, Register x2, Register b2 ) { emit_48( DDB_ZOPC  | fregt( f1, 8, 48)  | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_deb(  FloatRegister r1, const Address& a)                      { z_deb(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_ddb(  FloatRegister r1, const Address& a)                      { z_ddb(  r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+
+//---------------
+// square root
+//---------------
+inline void Assembler::z_sqdbr(FloatRegister f1, FloatRegister f2)                       { emit_32(SQDBR_ZOPC | fregt(f1, 24, 32)  | freg(f2, 28, 32)); }
+inline void Assembler::z_sqdb( FloatRegister fr1, int64_t d2, Register x2, Register b2 ) { emit_48( SQDB_ZOPC | fregt( fr1, 8, 48) | uimm12( d2, 20, 48) | reg( x2, 12, 48) | regz( b2, 16, 48));}
+inline void Assembler::z_sqdb( FloatRegister fr1, int64_t d2, Register b2)               { z_sqdb( fr1, d2, Z_R0, b2);}
+
+
+//---------------
+// CMP
+//---------------
+inline void Assembler::z_cebr(FloatRegister r1, FloatRegister r2)                    { emit_32( CEBR_ZOPC | fregt(r1, 24, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_ceb(FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_48( CEB_ZOPC  | fregt(r1, 8, 48) | uimm12(d2, 20, 48) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_ceb(FloatRegister r1, const Address &a)                     { z_ceb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+inline void Assembler::z_cdbr(FloatRegister r1, FloatRegister r2)                    { emit_32( CDBR_ZOPC | fregt(r1, 24, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_cdb(FloatRegister r1, int64_t d2, Register x2, Register b2) { emit_48( CDB_ZOPC  | fregt(r1, 8, 48) | uimm12(d2, 20, 48) | reg(x2, 12, 48) | regz(b2, 16, 48)); }
+inline void Assembler::z_cdb(FloatRegister r1, const Address &a)                     { z_cdb(r1, a.disp(), a.indexOrR0(), a.baseOrR0()); }
+
+
+//------------------------------------
+// FLOAT <-> INT conversion
+//------------------------------------
+inline void Assembler::z_ldgr(FloatRegister r1, Register r2)                  { emit_32( LDGR_ZOPC  | fregt(r1, 24, 32)  | reg(r2, 28, 32));  }
+inline void Assembler::z_lgdr(Register r1, FloatRegister r2)                  { emit_32( LGDR_ZOPC  | regt( r1, 24, 32)  | freg(r2, 28, 32)); }
+
+inline void Assembler::z_cefbr( FloatRegister r1, Register r2)                { emit_32( CEFBR_ZOPC | fregt( r1, 24, 32) | reg( r2, 28, 32)); }
+inline void Assembler::z_cdfbr( FloatRegister r1, Register r2)                { emit_32( CDFBR_ZOPC | fregt( r1, 24, 32) | reg( r2, 28, 32)); }
+inline void Assembler::z_cegbr( FloatRegister r1, Register r2)                { emit_32( CEGBR_ZOPC | fregt( r1, 24, 32) | reg( r2, 28, 32)); }
+inline void Assembler::z_cdgbr( FloatRegister r1, Register r2)                { emit_32( CDGBR_ZOPC | fregt( r1, 24, 32) | reg( r2, 28, 32)); }
+
+inline void Assembler::z_cfebr(Register r1, FloatRegister r2, RoundingMode m) { emit_32( CFEBR_ZOPC | regt(r1, 24, 32) | rounding_mode(m, 16, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_cfdbr(Register r1, FloatRegister r2, RoundingMode m) { emit_32( CFDBR_ZOPC | regt(r1, 24, 32) | rounding_mode(m, 16, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_cgebr(Register r1, FloatRegister r2, RoundingMode m) { emit_32( CGEBR_ZOPC | regt(r1, 24, 32) | rounding_mode(m, 16, 32) | freg(r2, 28, 32)); }
+inline void Assembler::z_cgdbr(Register r1, FloatRegister r2, RoundingMode m) { emit_32( CGDBR_ZOPC | regt(r1, 24, 32) | rounding_mode(m, 16, 32) | freg(r2, 28, 32)); }
+
+
+  inline void Assembler::z_layz(Register r1, int64_t d2, Register b2)      { z_layz(r1, d2, Z_R0, b2); }
+  inline void Assembler::z_lay(Register r1, int64_t d2, Register b2)       { z_lay( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_laz(Register r1, int64_t d2, Register b2)       { z_laz( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_la(Register r1, int64_t d2, Register b2)        { z_la(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_l(Register r1, int64_t d2, Register b2)         { z_l(   r1, d2, Z_R0, b2); }
+  inline void Assembler::z_ly(Register r1, int64_t d2, Register b2)        { z_ly(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_lg(Register r1, int64_t d2, Register b2)        { z_lg(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_st(Register r1, int64_t d2, Register b2)        { z_st(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_sty(Register r1, int64_t d2, Register b2)       { z_sty( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_stg(Register r1, int64_t d2, Register b2)       { z_stg( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_lgf(Register r1, int64_t d2, Register b2)       { z_lgf( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_lgh(Register r1, int64_t d2, Register b2)       { z_lgh( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_llgh(Register r1, int64_t d2, Register b2)      { z_llgh(r1, d2, Z_R0, b2); }
+  inline void Assembler::z_llgf(Register r1, int64_t d2, Register b2)      { z_llgf(r1, d2, Z_R0, b2); }
+  inline void Assembler::z_lgb(Register r1, int64_t d2, Register b2)       { z_lgb( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_cl( Register r1, int64_t d2, Register b2)       { z_cl(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_c(Register r1, int64_t d2, Register b2)         { z_c(   r1, d2, Z_R0, b2); }
+  inline void Assembler::z_cg(Register r1, int64_t d2, Register b2)        { z_cg(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_sh(Register r1, int64_t d2, Register b2)        { z_sh(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_shy(Register r1, int64_t d2, Register b2)       { z_shy( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_ste(FloatRegister r1, int64_t d2, Register b2)  { z_ste( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_std(FloatRegister r1, int64_t d2, Register b2)  { z_std( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_stdy(FloatRegister r1, int64_t d2, Register b2) { z_stdy(r1, d2, Z_R0, b2); }
+  inline void Assembler::z_stey(FloatRegister r1, int64_t d2, Register b2) { z_stey(r1, d2, Z_R0, b2); }
+  inline void Assembler::z_ld(FloatRegister r1, int64_t d2, Register b2)   { z_ld(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_ldy(FloatRegister r1, int64_t d2, Register b2)  { z_ldy( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_le(FloatRegister r1, int64_t d2, Register b2)   { z_le(  r1, d2, Z_R0, b2); }
+  inline void Assembler::z_ley(FloatRegister r1, int64_t d2, Register b2)  { z_ley( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_agf(Register r1, int64_t d2, Register b2)       { z_agf( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_cvd(Register r1, int64_t d2, Register b2)       { z_cvd( r1, d2, Z_R0, b2); }
+  inline void Assembler::z_cvdg(Register r1, int64_t d2, Register b2)      { z_cvdg(r1, d2, Z_R0, b2); }
+
+// signed comparison
+inline void Assembler::z_crj(Register r1, Register r2, branch_condition m3, Label& L)   { z_crj(  r1, r2, m3, target(L)); }
+inline void Assembler::z_cgrj(Register r1, Register r2, branch_condition m3, Label& L)  { z_cgrj( r1, r2, m3, target(L)); }
+inline void Assembler::z_cij(Register r1, int64_t i2, branch_condition m3, Label& L)    { z_cij(  r1, i2, m3, target(L)); }
+inline void Assembler::z_cgij(Register r1, int64_t i2, branch_condition m3, Label& L)   { z_cgij( r1, i2, m3, target(L)); }
+// unsigned comparison
+inline void Assembler::z_clrj(Register r1, Register r2, branch_condition m3, Label& L)  { z_clrj( r1, r2, m3, target(L)); }
+inline void Assembler::z_clgrj(Register r1, Register r2, branch_condition m3, Label& L) { z_clgrj(r1, r2, m3, target(L)); }
+inline void Assembler::z_clij(Register r1, int64_t i2, branch_condition m3, Label& L)   { z_clij( r1, i2, m3, target(L)); }
+inline void Assembler::z_clgij(Register r1, int64_t i2, branch_condition m3, Label& L)  { z_clgij(r1, i2, m3, target(L)); }
+
+// branch never (nop), branch always
+inline void Assembler::z_nop() { z_bcr(bcondNop, Z_R0); }
+inline void Assembler::z_br(Register r2) { assert(r2 != Z_R0, "nop if target is Z_R0, use z_nop() instead"); z_bcr(bcondAlways, r2 ); }
+
+inline void Assembler::z_exrl(Register r1, Label& L) { z_exrl(r1, target(L)); }  // z10
+inline void Assembler::z_larl(Register r1, Label& L) { z_larl(r1, target(L)); }
+inline void Assembler::z_bru(   Label& L) { z_brc(bcondAlways,target(L)); }
+inline void Assembler::z_brul(  Label& L) { z_brcl(bcondAlways,target(L)); }
+inline void Assembler::z_brul( address a) { z_brcl(bcondAlways,a); }
+inline void Assembler::z_brh(   Label& L) { z_brc(bcondHigh,target(L)); }
+inline void Assembler::z_brl(   Label& L) { z_brc(bcondLow,target(L)); }
+inline void Assembler::z_bre(   Label& L) { z_brc(bcondEqual,target(L)); }
+inline void Assembler::z_brnh(  Label& L) { z_brc(bcondNotHigh,target(L)); }
+inline void Assembler::z_brnl(  Label& L) { z_brc(bcondNotLow,target(L)); }
+inline void Assembler::z_brne(  Label& L) { z_brc(bcondNotEqual,target(L)); }
+inline void Assembler::z_brz(   Label& L) { z_brc(bcondZero,target(L)); }
+inline void Assembler::z_brnz(  Label& L) { z_brc(bcondNotZero,target(L)); }
+inline void Assembler::z_braz(  Label& L) { z_brc(bcondAllZero,target(L)); }
+inline void Assembler::z_brnaz( Label& L) { z_brc(bcondNotAllZero,target(L)); }
+inline void Assembler::z_brnp(  Label& L) { z_brc( bcondNotPositive, target( L)); }
+inline void Assembler::z_btrue( Label& L) { z_brc(bcondAllOne,target(L)); }
+inline void Assembler::z_bfalse(Label& L) { z_brc(bcondAllZero,target(L)); }
+inline void Assembler::z_brno(  Label& L) { z_brc(bcondNotOrdered,target(L)); }
+inline void Assembler::z_brc( branch_condition m, Label& L) { z_brc(m, target(L)); }
+inline void Assembler::z_brcl(branch_condition m, Label& L) { z_brcl(m, target(L)); }
+
+
+// Instruction must start at passed address.
+// Extra check for illtraps with ID.
+inline int Assembler::instr_len(unsigned char *instr) {
+  switch ((*instr) >> 6) {
+    case 0: return 2;
+    case 1: // fallthru
+    case 2: return 4;
+    case 3: return 6;
+    default:
+      // Control can't reach here.
+      // The switch expression examines just the leftmost two bytes
+      // of the main opcode. So the range of values is just [0..3].
+      // Having a default clause makes the compiler happy.
+      ShouldNotReachHere();
+      return 0;
+  }
+}
+
+// Move instr at pc right-justified into passed long int.
+// Return instr len in bytes as function result.
+// Note: 2-byte instr don't really need to be accessed unsigned
+// because leftmost two bits are always zero. We use
+// unsigned here for reasons of uniformity.
+inline unsigned int Assembler::get_instruction(unsigned char *pc, unsigned long *instr) {
+  unsigned int len = instr_len(pc);
+  switch (len) {
+    case 2:
+      *instr = *(unsigned short*) pc; break;
+    case 4:
+      *instr = *(unsigned int*) pc; break;
+    case 6:
+      // Must compose this case. Can't read 8 bytes and then cut off
+      // the rightmost two bytes. Could potentially access
+      // unallocated storage.
+      *instr = ((unsigned long)(*(unsigned int*)   pc)) << 16 |
+               ((unsigned long)*(unsigned short*) (pc + 4)); break;
+    default:
+      // Control can't reach here.
+      // The length as returned from instr_len() can only be 2, 4, or 6 bytes.
+      // Having a default clause makes the compiler happy.
+      ShouldNotReachHere();
+      break;
+  }
+  return len;
+}
+
+// Check if instruction is the expected one.
+// Instruction is passed right-justified in inst.
+inline bool Assembler::is_equal(unsigned long inst, unsigned long idef) {
+  unsigned long imask;
+
+  if ((idef >> 32) != 0) { // 6byte instructions
+    switch (idef >> 40) {  // select mask by main opcode
+      case 0xc0:
+      case 0xc2:
+      case 0xc4:
+      case 0xc6: imask = RIL_MASK; break;
+      case 0xec:
+        if ((idef & 0x00ffL) < 0x0080L) {
+          imask = RIE_MASK;
+          break;
+        }
+        // Fallthru for other sub opcodes.
+      default:
+#ifdef ASSERT
+        tty->print_cr("inst = %16.16lx, idef = %16.16lx, imask unspecified\n", inst, idef);
+        tty->flush();
+#endif
+        ShouldNotReachHere();
+        return 0;
+    }
+  } else {                 // 4-byte instructions
+    switch (idef >> 24) {  // Select mask by main opcode.
+      case 0x84:
+      case 0x85: imask = RSI_MASK; break;
+      case 0xa5:
+      case 0xa7: imask =  RI_MASK; break;
+      case 0xb9: imask = RRE_MASK; break; // RRE_MASK or RRF_MASK. Opcode fields are at same bit positions.
+      default: {
+#ifdef ASSERT
+        tty->print_cr("inst = %16.16lx, idef = %16.16lx, imask unspecified\n", inst, idef);
+        tty->flush();
+#endif
+        ShouldNotReachHere();
+        return 0;
+      }
+    }
+  }
+  return (inst & imask) == idef;
+}
+
+inline bool Assembler::is_equal(unsigned long inst, unsigned long idef, unsigned long imask) {
+  assert(imask != 0, "valid instruction mask required");
+  return (inst & imask) == idef;
+}
+
+// Check if instruction is the expected one.
+// Instruction is passed left-justified at inst.
+inline bool Assembler::is_equal(address iloc, unsigned long idef) {
+  unsigned long inst;
+  get_instruction(iloc, &inst);
+  return is_equal(inst, idef);
+}
+
+inline bool Assembler::is_equal(address iloc, unsigned long idef, unsigned long imask) {
+  unsigned long inst;
+  get_instruction(iloc, &inst);
+  return is_equal(inst, idef, imask);
+}
+
+inline bool Assembler::is_sigtrap_range_check(address pc) {
+  return (is_equal(pc, CLFIT_ZOPC, RIE_MASK) || is_equal(pc, CLRT_ZOPC, RRE_MASK));
+}
+
+inline bool Assembler::is_sigtrap_zero_check(address pc) {
+  return (is_equal(pc, CGIT_ZOPC, RIE_MASK) || is_equal(pc, CIT_ZOPC, RIE_MASK));
+}
+
+#endif // CPU_S390_VM_ASSEMBLER_S390_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/bytes_s390.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_BYTES_S390_HPP
+#define CPU_S390_VM_BYTES_S390_HPP
+
+#include "memory/allocation.hpp"
+
+class Bytes: AllStatic {
+ public:
+  // Efficient reading and writing of unaligned unsigned data in
+  // platform-specific byte ordering.
+
+  // Use regular load and store for unaligned access.
+  //
+  // On z/Architecture, unaligned loads and stores are supported when using the
+  // "traditional" load (LH, L/LY, LG) and store (STH, ST/STY, STG) instructions.
+  // The penalty for unaligned access is just very few (two or three) ticks,
+  // plus another few (two or three) ticks if the access crosses a cache line boundary.
+  //
+  // In short, it makes no sense on z/Architecture to piecemeal get or put unaligned data.
+
+  // Returns true if the byte ordering used by Java is different from
+  // the native byte ordering of the underlying machine.
+  // z/Arch is big endian, thus, a swap between native and Java ordering
+  // is always a no-op.
+  static inline bool is_Java_byte_ordering_different() { return false; }
+
+  // Only swap on little endian machines => suffix `_le'.
+  static inline u2   swap_u2_le(u2 x) { return x; }
+  static inline u4   swap_u4_le(u4 x) { return x; }
+  static inline u8   swap_u8_le(u8 x) { return x; }
+
+  static inline u2   get_native_u2(address p) { return *(u2*)p; }
+  static inline u4   get_native_u4(address p) { return *(u4*)p; }
+  static inline u8   get_native_u8(address p) { return *(u8*)p; }
+
+  static inline void put_native_u2(address p, u2 x) { *(u2*)p = x; }
+  static inline void put_native_u4(address p, u4 x) { *(u4*)p = x; }
+  static inline void put_native_u8(address p, u8 x) { *(u8*)p = x; }
+
+#include "bytes_linux_s390.inline.hpp"
+
+  // Efficient reading and writing of unaligned unsigned data in Java byte ordering (i.e. big-endian ordering)
+  static inline u2   get_Java_u2(address p) { return get_native_u2(p); }
+  static inline u4   get_Java_u4(address p) { return get_native_u4(p); }
+  static inline u8   get_Java_u8(address p) { return get_native_u8(p); }
+
+  static inline void put_Java_u2(address p, u2 x) { put_native_u2(p, x); }
+  static inline void put_Java_u4(address p, u4 x) { put_native_u4(p, x); }
+  static inline void put_Java_u8(address p, u8 x) { put_native_u8(p, x); }
+};
+
+#endif // CPU_S390_VM_BYTES_S390_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_CodeStubs_s390.cpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,497 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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 "precompiled.hpp"
+#include "c1/c1_CodeStubs.hpp"
+#include "c1/c1_FrameMap.hpp"
+#include "c1/c1_LIRAssembler.hpp"
+#include "c1/c1_MacroAssembler.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "nativeInst_s390.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "utilities/macros.hpp"
+#include "vmreg_s390.inline.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc/g1/g1SATBCardTableModRefBS.hpp"
+#endif // INCLUDE_ALL_GCS
+
+#define __ ce->masm()->
+#undef  CHECK_BAILOUT
+#define CHECK_BAILOUT() { if (ce->compilation()->bailed_out()) return; }
+
+RangeCheckStub::RangeCheckStub(CodeEmitInfo* info, LIR_Opr index,
+                               bool throw_index_out_of_bounds_exception) :
+  _throw_index_out_of_bounds_exception(throw_index_out_of_bounds_exception),
+  _index(index) {
+  assert(info != NULL, "must have info");
+  _info = new CodeEmitInfo(info);
+}
+
+void RangeCheckStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  if (_info->deoptimize_on_exception()) {
+    address a = Runtime1::entry_for (Runtime1::predicate_failed_trap_id);
+    ce->emit_call_c(a);
+    CHECK_BAILOUT();
+    ce->add_call_info_here(_info);
+    ce->verify_oop_map(_info);
+    debug_only(__ should_not_reach_here());
+    return;
+  }
+
+  // Pass the array index in Z_R1_scratch which is not managed by linear scan.
+  if (_index->is_cpu_register()) {
+    __ lgr_if_needed(Z_R1_scratch, _index->as_register());
+  } else {
+    __ load_const_optimized(Z_R1_scratch, _index->as_jint());
+  }
+
+  Runtime1::StubID stub_id;
+  if (_throw_index_out_of_bounds_exception) {
+    stub_id = Runtime1::throw_index_exception_id;
+  } else {
+    stub_id = Runtime1::throw_range_check_failed_id;
+  }
+  ce->emit_call_c(Runtime1::entry_for (stub_id));
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+PredicateFailedStub::PredicateFailedStub(CodeEmitInfo* info) {
+  _info = new CodeEmitInfo(info);
+}
+
+void PredicateFailedStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  address a = Runtime1::entry_for (Runtime1::predicate_failed_trap_id);
+  ce->emit_call_c(a);
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+void CounterOverflowStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  Metadata *m = _method->as_constant_ptr()->as_metadata();
+  bool success = __ set_metadata_constant(m, Z_R1_scratch);
+  if (!success) {
+    ce->compilation()->bailout("const section overflow");
+    return;
+  }
+  ce->store_parameter(/*_method->as_register()*/ Z_R1_scratch, 1);
+  ce->store_parameter(_bci, 0);
+  ce->emit_call_c(Runtime1::entry_for (Runtime1::counter_overflow_id));
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  __ branch_optimized(Assembler::bcondAlways, _continuation);
+}
+
+void DivByZeroStub::emit_code(LIR_Assembler* ce) {
+  if (_offset != -1) {
+    ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
+  }
+  __ bind(_entry);
+  ce->emit_call_c(Runtime1::entry_for (Runtime1::throw_div0_exception_id));
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+void ImplicitNullCheckStub::emit_code(LIR_Assembler* ce) {
+  address a;
+  if (_info->deoptimize_on_exception()) {
+    // Deoptimize, do not throw the exception, because it is probably wrong to do it here.
+    a = Runtime1::entry_for (Runtime1::predicate_failed_trap_id);
+  } else {
+    a = Runtime1::entry_for (Runtime1::throw_null_pointer_exception_id);
+  }
+
+  ce->compilation()->implicit_exception_table()->append(_offset, __ offset());
+  __ bind(_entry);
+  ce->emit_call_c(a);
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+// Note: pass object in Z_R1_scratch
+void SimpleExceptionStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  if (_obj->is_valid()) {
+    __ z_lgr(Z_R1_scratch, _obj->as_register()); // _obj contains the optional argument to the stub
+  }
+  address a = Runtime1::entry_for (_stub);
+  ce->emit_call_c(a);
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  debug_only(__ should_not_reach_here());
+}
+
+NewInstanceStub::NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id) {
+  _result = result;
+  _klass = klass;
+  _klass_reg = klass_reg;
+  _info = new CodeEmitInfo(info);
+  assert(stub_id == Runtime1::new_instance_id                 ||
+         stub_id == Runtime1::fast_new_instance_id            ||
+         stub_id == Runtime1::fast_new_instance_init_check_id,
+         "need new_instance id");
+  _stub_id = stub_id;
+}
+
+void NewInstanceStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  assert(_klass_reg->as_register() == Z_R11, "call target expects klass in Z_R11");
+  address a = Runtime1::entry_for (_stub_id);
+  ce->emit_call_c(a);
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  assert(_result->as_register() == Z_R2, "callee returns result in Z_R2,");
+  __ z_brul(_continuation);
+}
+
+NewTypeArrayStub::NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
+  _klass_reg = klass_reg;
+  _length = length;
+  _result = result;
+  _info = new CodeEmitInfo(info);
+}
+
+void NewTypeArrayStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  assert(_klass_reg->as_register() == Z_R11, "call target expects klass in Z_R11");
+  __ lgr_if_needed(Z_R13, _length->as_register());
+  address a = Runtime1::entry_for (Runtime1::new_type_array_id);
+  ce->emit_call_c(a);
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  assert(_result->as_register() == Z_R2, "callee returns result in Z_R2,");
+  __ z_brul(_continuation);
+}
+
+NewObjectArrayStub::NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info) {
+  _klass_reg = klass_reg;
+  _length = length;
+  _result = result;
+  _info = new CodeEmitInfo(info);
+}
+
+void NewObjectArrayStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  assert(_klass_reg->as_register() == Z_R11, "call target expects klass in Z_R11");
+  __ lgr_if_needed(Z_R13, _length->as_register());
+  address a = Runtime1::entry_for (Runtime1::new_object_array_id);
+  ce->emit_call_c(a);
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  assert(_result->as_register() == Z_R2, "callee returns result in Z_R2,");
+  __ z_brul(_continuation);
+}
+
+MonitorEnterStub::MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info)
+  : MonitorAccessStub(obj_reg, lock_reg) {
+  _info = new CodeEmitInfo(info);
+}
+
+void MonitorEnterStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  Runtime1::StubID enter_id;
+  if (ce->compilation()->has_fpu_code()) {
+    enter_id = Runtime1::monitorenter_id;
+  } else {
+    enter_id = Runtime1::monitorenter_nofpu_id;
+  }
+  __ lgr_if_needed(Z_R1_scratch, _obj_reg->as_register());
+  __ lgr_if_needed(Z_R13, _lock_reg->as_register()); // See LIRGenerator::syncTempOpr().
+  ce->emit_call_c(Runtime1::entry_for (enter_id));
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  ce->verify_oop_map(_info);
+  __ branch_optimized(Assembler::bcondAlways, _continuation);
+}
+
+void MonitorExitStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  // Move address of the BasicObjectLock into Z_R1_scratch.
+  if (_compute_lock) {
+    // Lock_reg was destroyed by fast unlocking attempt => recompute it.
+    ce->monitor_address(_monitor_ix, FrameMap::as_opr(Z_R1_scratch));
+  } else {
+    __ lgr_if_needed(Z_R1_scratch, _lock_reg->as_register());
+  }
+  // Note: non-blocking leaf routine => no call info needed.
+  Runtime1::StubID exit_id;
+  if (ce->compilation()->has_fpu_code()) {
+    exit_id = Runtime1::monitorexit_id;
+  } else {
+    exit_id = Runtime1::monitorexit_nofpu_id;
+  }
+  ce->emit_call_c(Runtime1::entry_for (exit_id));
+  CHECK_BAILOUT();
+  __ branch_optimized(Assembler::bcondAlways, _continuation);
+}
+
+// Implementation of patching:
+// - Copy the code at given offset to an inlined buffer (first the bytes, then the number of bytes).
+// - Replace original code with a call to the stub.
+// At Runtime:
+// - call to stub, jump to runtime.
+// - in runtime: Preserve all registers (especially objects, i.e., source and destination object).
+// - in runtime: After initializing class, restore original code, reexecute instruction.
+
+int PatchingStub::_patch_info_offset = - (12 /* load const */ + 2 /*BASR*/);
+
+void PatchingStub::align_patch_site(MacroAssembler* masm) {
+#ifndef PRODUCT
+  const char* bc;
+  switch (_id) {
+  case access_field_id: bc = "patch site (access_field)"; break;
+  case load_klass_id: bc = "patch site (load_klass)"; break;
+  case load_mirror_id: bc = "patch site (load_mirror)"; break;
+  case load_appendix_id: bc = "patch site (load_appendix)"; break;
+  default: bc = "patch site (unknown patch id)"; break;
+  }
+  masm->block_comment(bc);
+#endif
+
+  masm->align(round_to(NativeGeneralJump::instruction_size, wordSize));
+}
+
+void PatchingStub::emit_code(LIR_Assembler* ce) {
+  // Copy original code here.
+  assert(NativeGeneralJump::instruction_size <= _bytes_to_copy && _bytes_to_copy <= 0xFF,
+         "not enough room for call");
+
+  NearLabel call_patch;
+
+  int being_initialized_entry = __ offset();
+
+  if (_id == load_klass_id) {
+    // Produce a copy of the load klass instruction for use by the case being initialized.
+#ifdef ASSERT
+    address start = __ pc();
+#endif
+    AddressLiteral addrlit((intptr_t)0, metadata_Relocation::spec(_index));
+    __ load_const(_obj, addrlit);
+
+#ifdef ASSERT
+    for (int i = 0; i < _bytes_to_copy; i++) {
+      address ptr = (address)(_pc_start + i);
+      int a_byte = (*ptr) & 0xFF;
+      assert(a_byte == *start++, "should be the same code");
+    }
+#endif
+  } else if (_id == load_mirror_id || _id == load_appendix_id) {
+    // Produce a copy of the load mirror instruction for use by the case being initialized.
+#ifdef ASSERT
+    address start = __ pc();
+#endif
+    AddressLiteral addrlit((intptr_t)0, oop_Relocation::spec(_index));
+    __ load_const(_obj, addrlit);
+
+#ifdef ASSERT
+    for (int i = 0; i < _bytes_to_copy; i++) {
+      address ptr = (address)(_pc_start + i);
+      int a_byte = (*ptr) & 0xFF;
+      assert(a_byte == *start++, "should be the same code");
+    }
+#endif
+  } else {
+    // Make a copy the code which is going to be patched.
+    for (int i = 0; i < _bytes_to_copy; i++) {
+      address ptr = (address)(_pc_start + i);
+      int a_byte = (*ptr) & 0xFF;
+      __ emit_int8 (a_byte);
+    }
+  }
+
+  address end_of_patch = __ pc();
+  int bytes_to_skip = 0;
+  if (_id == load_mirror_id) {
+    int offset = __ offset();
+    if (CommentedAssembly) {
+      __ block_comment(" being_initialized check");
+    }
+
+    // Static field accesses have special semantics while the class
+    // initializer is being run, so we emit a test which can be used to
+    // check that this code is being executed by the initializing
+    // thread.
+    assert(_obj != noreg, "must be a valid register");
+    assert(_index >= 0, "must have oop index");
+    __ z_lg(Z_R1_scratch, java_lang_Class::klass_offset_in_bytes(), _obj);
+    __ z_cg(Z_thread, Address(Z_R1_scratch, InstanceKlass::init_thread_offset()));
+    __ branch_optimized(Assembler::bcondNotEqual, call_patch);
+
+    // Load_klass patches may execute the patched code before it's
+    // copied back into place so we need to jump back into the main
+    // code of the nmethod to continue execution.
+    __ branch_optimized(Assembler::bcondAlways, _patch_site_continuation);
+
+    // Make sure this extra code gets skipped.
+    bytes_to_skip += __ offset() - offset;
+  }
+
+  // Now emit the patch record telling the runtime how to find the
+  // pieces of the patch. We only need 3 bytes but to help the disassembler
+  // we make the data look like a the following add instruction:
+  //   A R1, D2(X2, B2)
+  // which requires 4 bytes.
+  int sizeof_patch_record = 4;
+  bytes_to_skip += sizeof_patch_record;
+
+  // Emit the offsets needed to find the code to patch.
+  int being_initialized_entry_offset = __ offset() - being_initialized_entry + sizeof_patch_record;
+
+  // Emit the patch record: opcode of the add followed by 3 bytes patch record data.
+  __ emit_int8((int8_t)(A_ZOPC>>24));
+  __ emit_int8(being_initialized_entry_offset);
+  __ emit_int8(bytes_to_skip);
+  __ emit_int8(_bytes_to_copy);
+  address patch_info_pc = __ pc();
+  assert(patch_info_pc - end_of_patch == bytes_to_skip, "incorrect patch info");
+
+  address entry = __ pc();
+  NativeGeneralJump::insert_unconditional((address)_pc_start, entry);
+  address target = NULL;
+  relocInfo::relocType reloc_type = relocInfo::none;
+  switch (_id) {
+    case access_field_id:  target = Runtime1::entry_for (Runtime1::access_field_patching_id); break;
+    case load_klass_id:    target = Runtime1::entry_for (Runtime1::load_klass_patching_id); reloc_type = relocInfo::metadata_type; break;
+    case load_mirror_id:   target = Runtime1::entry_for (Runtime1::load_mirror_patching_id); reloc_type = relocInfo::oop_type; break;
+    case load_appendix_id: target = Runtime1::entry_for (Runtime1::load_appendix_patching_id); reloc_type = relocInfo::oop_type; break;
+    default: ShouldNotReachHere();
+  }
+  __ bind(call_patch);
+
+  if (CommentedAssembly) {
+    __ block_comment("patch entry point");
+  }
+  // Cannot use call_c_opt() because its size is not constant.
+  __ load_const(Z_R1_scratch, target); // Must not optimize in order to keep constant _patch_info_offset constant.
+  __ z_basr(Z_R14, Z_R1_scratch);
+  assert(_patch_info_offset == (patch_info_pc - __ pc()), "must not change");
+  ce->add_call_info_here(_info);
+  __ z_brcl(Assembler::bcondAlways, _patch_site_entry);
+  if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
+    CodeSection* cs = __ code_section();
+    address pc = (address)_pc_start;
+    RelocIterator iter(cs, pc, pc + 1);
+    relocInfo::change_reloc_info_for_address(&iter, (address) pc, reloc_type, relocInfo::none);
+  }
+}
+
+void DeoptimizeStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  __ load_const_optimized(Z_R1_scratch, _trap_request); // Pass trap request in Z_R1_scratch.
+  ce->emit_call_c(Runtime1::entry_for (Runtime1::deoptimize_id));
+  CHECK_BAILOUT();
+  ce->add_call_info_here(_info);
+  DEBUG_ONLY(__ should_not_reach_here());
+}
+
+void ArrayCopyStub::emit_code(LIR_Assembler* ce) {
+  // Slow case: call to native.
+  __ bind(_entry);
+  __ lgr_if_needed(Z_ARG1, src()->as_register());
+  __ lgr_if_needed(Z_ARG2, src_pos()->as_register());
+  __ lgr_if_needed(Z_ARG3, dst()->as_register());
+  __ lgr_if_needed(Z_ARG4, dst_pos()->as_register());
+  __ lgr_if_needed(Z_ARG5, length()->as_register());
+
+  // Must align calls sites, otherwise they can't be updated atomically on MP hardware.
+  ce->align_call(lir_static_call);
+
+  assert((__ offset() + NativeCall::call_far_pcrelative_displacement_offset) % NativeCall::call_far_pcrelative_displacement_alignment == 0,
+         "must be aligned");
+
+  ce->emit_static_call_stub();
+
+  // Prepend each BRASL with a nop.
+  __ relocate(relocInfo::static_call_type);
+  __ z_nop();
+  __ z_brasl(Z_R14, SharedRuntime::get_resolve_static_call_stub());
+  ce->add_call_info_here(info());
+  ce->verify_oop_map(info());
+
+#ifndef PRODUCT
+  __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_arraycopy_slowcase_cnt);
+  __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
+#endif
+
+  __ branch_optimized(Assembler::bcondAlways, _continuation);
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+#if INCLUDE_ALL_GCS
+
+void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
+  // At this point we know that marking is in progress.
+  // If do_load() is true then we have to emit the
+  // load of the previous value; otherwise it has already
+  // been loaded into _pre_val.
+  __ bind(_entry);
+  ce->check_reserved_argument_area(16); // RT stub needs 2 spill slots.
+  assert(pre_val()->is_register(), "Precondition.");
+
+  Register pre_val_reg = pre_val()->as_register();
+
+  if (do_load()) {
+    ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false /*wide*/, false /*unaligned*/);
+  }
+
+  __ z_ltgr(Z_R1_scratch, pre_val_reg); // Pass oop in Z_R1_scratch to Runtime1::g1_pre_barrier_slow_id.
+  __ branch_optimized(Assembler::bcondZero, _continuation);
+  ce->emit_call_c(Runtime1::entry_for (Runtime1::g1_pre_barrier_slow_id));
+  CHECK_BAILOUT();
+  __ branch_optimized(Assembler::bcondAlways, _continuation);
+}
+
+void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
+  __ bind(_entry);
+  ce->check_reserved_argument_area(16); // RT stub needs 2 spill slots.
+  assert(addr()->is_register(), "Precondition.");
+  assert(new_val()->is_register(), "Precondition.");
+  Register new_val_reg = new_val()->as_register();
+  __ z_ltgr(new_val_reg, new_val_reg);
+  __ branch_optimized(Assembler::bcondZero, _continuation);
+  __ z_lgr(Z_R1_scratch, addr()->as_pointer_register());
+  ce->emit_call_c(Runtime1::entry_for (Runtime1::g1_post_barrier_slow_id));
+  CHECK_BAILOUT();
+  __ branch_optimized(Assembler::bcondAlways, _continuation);
+}
+
+#endif // INCLUDE_ALL_GCS
+
+#undef __
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_Defs_s390.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_C1_DEFS_S390_HPP
+#define CPU_S390_VM_C1_DEFS_S390_HPP
+
+// Native word offsets from memory address (big endian).
+enum {
+  pd_lo_word_offset_in_bytes = BytesPerInt,
+  pd_hi_word_offset_in_bytes = 0
+};
+
+// Explicit rounding operations are not required to implement the strictFP mode.
+enum {
+  pd_strict_fp_requires_explicit_rounding = false
+};
+
+// registers
+enum {
+  pd_nof_cpu_regs_frame_map = 16,  // Number of registers used during code emission.
+  // Treat all registers as caller save (values of callee save are hard to find if caller is in runtime).
+  // unallocated: Z_thread, Z_fp, Z_SP, Z_R0_scratch, Z_R1_scratch, Z_R14
+  pd_nof_cpu_regs_unallocated = 6,
+  pd_nof_caller_save_cpu_regs_frame_map = pd_nof_cpu_regs_frame_map - pd_nof_cpu_regs_unallocated,  // Number of cpu registers killed by calls.
+  pd_nof_cpu_regs_reg_alloc = pd_nof_caller_save_cpu_regs_frame_map,  // Number of registers that are visible to register allocator.
+  pd_nof_cpu_regs_linearscan = pd_nof_cpu_regs_frame_map,// Number of registers visible linear scan.
+  pd_first_cpu_reg = 0,
+  pd_last_cpu_reg  = 9, // Others are unallocated (see FrameMap::initialize()).
+
+  pd_nof_fpu_regs_frame_map = 16,  // Number of registers used during code emission.
+  pd_nof_fcpu_regs_unallocated = 1, // Leave Z_F15 unallocated and use it as scratch register.
+  pd_nof_caller_save_fpu_regs_frame_map = pd_nof_fpu_regs_frame_map - pd_nof_fcpu_regs_unallocated,  // Number of fpu registers killed by calls.
+  pd_nof_fpu_regs_reg_alloc = pd_nof_caller_save_fpu_regs_frame_map,  // Number of registers that are visible to register allocator.
+  pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // Number of registers visible to linear scan.
+  pd_first_fpu_reg = pd_nof_cpu_regs_frame_map,
+  pd_last_fpu_reg =  pd_first_fpu_reg + pd_nof_fpu_regs_frame_map - pd_nof_fcpu_regs_unallocated - 1,
+
+  pd_nof_xmm_regs_linearscan = 0,
+  pd_nof_caller_save_xmm_regs = 0,
+  pd_first_xmm_reg = -1,
+  pd_last_xmm_reg = -1
+};
+
+// For debug info: a float value in a register is saved in single precision by runtime stubs.
+enum {
+  pd_float_saved_as_double = false
+};
+
+#endif // CPU_S390_VM_C1_DEFS_S390_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_FpuStackSim_s390.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_C1_FPUSTACKSIM_S390_HPP
+#define CPU_S390_VM_C1_FPUSTACKSIM_S390_HPP
+
+// No FPU stack on ZARCH_64
+class FpuStackSim;
+
+#endif // CPU_S390_VM_C1_FPUSTACKSIM_S390_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_FrameMap_s390.cpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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 "precompiled.hpp"
+#include "c1/c1_FrameMap.hpp"
+#include "c1/c1_LIR.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "vmreg_s390.inline.hpp"
+
+
+const int FrameMap::pd_c_runtime_reserved_arg_size = 7;
+
+LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) {
+  LIR_Opr opr = LIR_OprFact::illegalOpr;
+  VMReg r_1 = reg->first();
+  VMReg r_2 = reg->second();
+  if (r_1->is_stack()) {
+    // Convert stack slot to an SP offset.
+    // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value
+    // so we must add it in here.
+    int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
+    opr = LIR_OprFact::address(new LIR_Address(Z_SP_opr, st_off, type));
+  } else if (r_1->is_Register()) {
+    Register reg = r_1->as_Register();
+    if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
+      opr = as_long_opr(reg);
+    } else if (type == T_OBJECT || type == T_ARRAY) {
+      opr = as_oop_opr(reg);
+    } else if (type == T_METADATA) {
+      opr = as_metadata_opr(reg);
+    } else {
+      opr = as_opr(reg);
+    }
+  } else if (r_1->is_FloatRegister()) {
+    assert(type == T_DOUBLE || type == T_FLOAT, "wrong type");
+    FloatRegister f = r_1->as_FloatRegister();
+    if (type == T_FLOAT) {
+      opr = as_float_opr(f);
+    } else {
+      opr = as_double_opr(f);
+    }
+  } else {
+    ShouldNotReachHere();
+  }
+  return opr;
+}
+
+//               FrameMap
+//--------------------------------------------------------
+
+FloatRegister FrameMap::_fpu_rnr2reg [FrameMap::nof_fpu_regs]; // mapping c1 regnr. -> FloatRegister
+int           FrameMap::_fpu_reg2rnr [FrameMap::nof_fpu_regs]; // mapping assembler encoding -> c1 regnr.
+
+// Some useful constant RInfo's:
+LIR_Opr FrameMap::Z_R0_opr;
+LIR_Opr FrameMap::Z_R1_opr;
+LIR_Opr FrameMap::Z_R2_opr;
+LIR_Opr FrameMap::Z_R3_opr;
+LIR_Opr FrameMap::Z_R4_opr;
+LIR_Opr FrameMap::Z_R5_opr;
+LIR_Opr FrameMap::Z_R6_opr;
+LIR_Opr FrameMap::Z_R7_opr;
+LIR_Opr FrameMap::Z_R8_opr;
+LIR_Opr FrameMap::Z_R9_opr;
+LIR_Opr FrameMap::Z_R10_opr;
+LIR_Opr FrameMap::Z_R11_opr;
+LIR_Opr FrameMap::Z_R12_opr;
+LIR_Opr FrameMap::Z_R13_opr;
+LIR_Opr FrameMap::Z_R14_opr;
+LIR_Opr FrameMap::Z_R15_opr;
+
+LIR_Opr FrameMap::Z_R0_oop_opr;
+LIR_Opr FrameMap::Z_R1_oop_opr;
+LIR_Opr FrameMap::Z_R2_oop_opr;
+LIR_Opr FrameMap::Z_R3_oop_opr;
+LIR_Opr FrameMap::Z_R4_oop_opr;
+LIR_Opr FrameMap::Z_R5_oop_opr;
+LIR_Opr FrameMap::Z_R6_oop_opr;
+LIR_Opr FrameMap::Z_R7_oop_opr;
+LIR_Opr FrameMap::Z_R8_oop_opr;
+LIR_Opr FrameMap::Z_R9_oop_opr;
+LIR_Opr FrameMap::Z_R10_oop_opr;
+LIR_Opr FrameMap::Z_R11_oop_opr;
+LIR_Opr FrameMap::Z_R12_oop_opr;
+LIR_Opr FrameMap::Z_R13_oop_opr;
+LIR_Opr FrameMap::Z_R14_oop_opr;
+LIR_Opr FrameMap::Z_R15_oop_opr;
+
+LIR_Opr FrameMap::Z_R0_metadata_opr;
+LIR_Opr FrameMap::Z_R1_metadata_opr;
+LIR_Opr FrameMap::Z_R2_metadata_opr;
+LIR_Opr FrameMap::Z_R3_metadata_opr;
+LIR_Opr FrameMap::Z_R4_metadata_opr;
+LIR_Opr FrameMap::Z_R5_metadata_opr;
+LIR_Opr FrameMap::Z_R6_metadata_opr;
+LIR_Opr FrameMap::Z_R7_metadata_opr;
+LIR_Opr FrameMap::Z_R8_metadata_opr;
+LIR_Opr FrameMap::Z_R9_metadata_opr;
+LIR_Opr FrameMap::Z_R10_metadata_opr;
+LIR_Opr FrameMap::Z_R11_metadata_opr;
+LIR_Opr FrameMap::Z_R12_metadata_opr;
+LIR_Opr FrameMap::Z_R13_metadata_opr;
+LIR_Opr FrameMap::Z_R14_metadata_opr;
+LIR_Opr FrameMap::Z_R15_metadata_opr;
+
+LIR_Opr FrameMap::Z_SP_opr;
+LIR_Opr FrameMap::Z_FP_opr;
+
+LIR_Opr FrameMap::Z_R2_long_opr;
+LIR_Opr FrameMap::Z_R10_long_opr;
+LIR_Opr FrameMap::Z_R11_long_opr;
+
+LIR_Opr FrameMap::Z_F0_opr;
+LIR_Opr FrameMap::Z_F0_double_opr;
+
+
+LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, };
+LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, };
+
+
+// c1 rnr -> FloatRegister
+FloatRegister FrameMap::nr2floatreg (int rnr) {
+  assert(_init_done, "tables not initialized");
+  debug_only(fpu_range_check(rnr);)
+  return _fpu_rnr2reg[rnr];
+}
+
+void FrameMap::map_float_register(int rnr, FloatRegister reg) {
+  debug_only(fpu_range_check(rnr);)
+  debug_only(fpu_range_check(reg->encoding());)
+  _fpu_rnr2reg[rnr] = reg;              // mapping c1 regnr. -> FloatRegister
+  _fpu_reg2rnr[reg->encoding()] = rnr;  // mapping assembler encoding -> c1 regnr.
+}
+
+void FrameMap::initialize() {
+  assert(!_init_done, "once");
+
+  DEBUG_ONLY(int allocated   = 0;)
+  DEBUG_ONLY(int unallocated = 0;)
+
+  // Register usage:
+  // Z_thread (Z_R8)
+  // Z_fp     (Z_R9)
+  // Z_SP     (Z_R15)
+  DEBUG_ONLY(allocated++); map_register(0, Z_R2);
+  DEBUG_ONLY(allocated++); map_register(1, Z_R3);
+  DEBUG_ONLY(allocated++); map_register(2, Z_R4);
+  DEBUG_ONLY(allocated++); map_register(3, Z_R5);
+  DEBUG_ONLY(allocated++); map_register(4, Z_R6);
+  DEBUG_ONLY(allocated++); map_register(5, Z_R7);
+  DEBUG_ONLY(allocated++); map_register(6, Z_R10);
+  DEBUG_ONLY(allocated++); map_register(7, Z_R11);
+  DEBUG_ONLY(allocated++); map_register(8, Z_R12);
+  DEBUG_ONLY(allocated++); map_register(9, Z_R13);     // <- last register visible in RegAlloc
+  DEBUG_ONLY(unallocated++); map_register(11, Z_R0);   // Z_R0_scratch
+  DEBUG_ONLY(unallocated++); map_register(12, Z_R1);   // Z_R1_scratch
+  DEBUG_ONLY(unallocated++); map_register(10, Z_R14);  // return pc; TODO: Try to let c1/c2 allocate R14.
+
+  // The following registers are usually unavailable.
+  DEBUG_ONLY(unallocated++); map_register(13, Z_R8);
+  DEBUG_ONLY(unallocated++); map_register(14, Z_R9);
+  DEBUG_ONLY(unallocated++); map_register(15, Z_R15);
+  assert(allocated-1 == pd_last_cpu_reg, "wrong number/mapping of allocated CPU registers");
+  assert(unallocated == pd_nof_cpu_regs_unallocated, "wrong number of unallocated CPU registers");
+  assert(nof_cpu_regs == allocated+unallocated, "wrong number of CPU registers");
+
+  int j = 0;
+  for (int i = 0; i < nof_fpu_regs; i++) {
+    if (as_FloatRegister(i) == Z_fscratch_1) continue; // unallocated
+    map_float_register(j++, as_FloatRegister(i));
+  }
+  assert(j == nof_fpu_regs-1, "missed one fpu reg?");
+  map_float_register(j++, Z_fscratch_1);
+
+  _init_done = true;
+
+  Z_R0_opr = as_opr(Z_R0);
+  Z_R1_opr = as_opr(Z_R1);
+  Z_R2_opr = as_opr(Z_R2);
+  Z_R3_opr = as_opr(Z_R3);
+  Z_R4_opr = as_opr(Z_R4);
+  Z_R5_opr = as_opr(Z_R5);
+  Z_R6_opr = as_opr(Z_R6);
+  Z_R7_opr = as_opr(Z_R7);
+  Z_R8_opr = as_opr(Z_R8);
+  Z_R9_opr = as_opr(Z_R9);
+  Z_R10_opr = as_opr(Z_R10);
+  Z_R11_opr = as_opr(Z_R11);
+  Z_R12_opr = as_opr(Z_R12);
+  Z_R13_opr = as_opr(Z_R13);
+  Z_R14_opr = as_opr(Z_R14);
+  Z_R15_opr = as_opr(Z_R15);
+
+  Z_R0_oop_opr = as_oop_opr(Z_R0);
+  Z_R1_oop_opr = as_oop_opr(Z_R1);
+  Z_R2_oop_opr = as_oop_opr(Z_R2);
+  Z_R3_oop_opr = as_oop_opr(Z_R3);
+  Z_R4_oop_opr = as_oop_opr(Z_R4);
+  Z_R5_oop_opr = as_oop_opr(Z_R5);
+  Z_R6_oop_opr = as_oop_opr(Z_R6);
+  Z_R7_oop_opr = as_oop_opr(Z_R7);
+  Z_R8_oop_opr = as_oop_opr(Z_R8);
+  Z_R9_oop_opr = as_oop_opr(Z_R9);
+  Z_R10_oop_opr = as_oop_opr(Z_R10);
+  Z_R11_oop_opr = as_oop_opr(Z_R11);
+  Z_R12_oop_opr = as_oop_opr(Z_R12);
+  Z_R13_oop_opr = as_oop_opr(Z_R13);
+  Z_R14_oop_opr = as_oop_opr(Z_R14);
+  Z_R15_oop_opr = as_oop_opr(Z_R15);
+
+  Z_R0_metadata_opr = as_metadata_opr(Z_R0);
+  Z_R1_metadata_opr = as_metadata_opr(Z_R1);
+  Z_R2_metadata_opr = as_metadata_opr(Z_R2);
+  Z_R3_metadata_opr = as_metadata_opr(Z_R3);
+  Z_R4_metadata_opr = as_metadata_opr(Z_R4);
+  Z_R5_metadata_opr = as_metadata_opr(Z_R5);
+  Z_R6_metadata_opr = as_metadata_opr(Z_R6);
+  Z_R7_metadata_opr = as_metadata_opr(Z_R7);
+  Z_R8_metadata_opr = as_metadata_opr(Z_R8);
+  Z_R9_metadata_opr = as_metadata_opr(Z_R9);
+  Z_R10_metadata_opr = as_metadata_opr(Z_R10);
+  Z_R11_metadata_opr = as_metadata_opr(Z_R11);
+  Z_R12_metadata_opr = as_metadata_opr(Z_R12);
+  Z_R13_metadata_opr = as_metadata_opr(Z_R13);
+  Z_R14_metadata_opr = as_metadata_opr(Z_R14);
+  Z_R15_metadata_opr = as_metadata_opr(Z_R15);
+
+  // TODO: needed? Or can we make Z_R9 available for linear scan allocation.
+  Z_FP_opr = as_pointer_opr(Z_fp);
+  Z_SP_opr = as_pointer_opr(Z_SP);
+
+  Z_R2_long_opr = LIR_OprFact::double_cpu(cpu_reg2rnr(Z_R2), cpu_reg2rnr(Z_R2));
+  Z_R10_long_opr = LIR_OprFact::double_cpu(cpu_reg2rnr(Z_R10), cpu_reg2rnr(Z_R10));
+  Z_R11_long_opr = LIR_OprFact::double_cpu(cpu_reg2rnr(Z_R11), cpu_reg2rnr(Z_R11));
+
+  Z_F0_opr = as_float_opr(Z_F0);
+  Z_F0_double_opr = as_double_opr(Z_F0);
+
+  // All allocated cpu regs are caller saved.
+  for (int c1rnr = 0; c1rnr < max_nof_caller_save_cpu_regs; c1rnr++) {
+    _caller_save_cpu_regs[c1rnr] = as_opr(cpu_rnr2reg(c1rnr));
+  }
+
+  // All allocated fpu regs are caller saved.
+  for (int c1rnr = 0; c1rnr < nof_caller_save_fpu_regs; c1rnr++) {
+    _caller_save_fpu_regs[c1rnr] = as_float_opr(nr2floatreg(c1rnr));
+  }
+}
+
+Address FrameMap::make_new_address(ByteSize sp_offset) const {
+  return Address(Z_SP, sp_offset);
+}
+
+VMReg FrameMap::fpu_regname (int n) {
+  return nr2floatreg(n)->as_VMReg();
+}
+
+LIR_Opr FrameMap::stack_pointer() {
+  return Z_SP_opr;
+}
+
+// JSR 292
+// On ZARCH_64, there is no need to save the SP, because neither
+// method handle intrinsics nor compiled lambda forms modify it.
+LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
+  return LIR_OprFact::illegalOpr;
+}
+
+bool FrameMap::validate_frame() {
+  return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_FrameMap_s390.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_C1_FRAMEMAP_S390_HPP
+#define CPU_S390_VM_C1_FRAMEMAP_S390_HPP
+
+ public:
+
+  enum {
+    nof_reg_args = 5,   // Registers Z_ARG1 - Z_ARG5 are available for parameter passing.
+    first_available_sp_in_frame = frame::z_abi_16_size,
+    frame_pad_in_bytes = 0
+  };
+
+  static const int pd_c_runtime_reserved_arg_size;
+
+  static LIR_Opr Z_R0_opr;
+  static LIR_Opr Z_R1_opr;
+  static LIR_Opr Z_R2_opr;
+  static LIR_Opr Z_R3_opr;
+  static LIR_Opr Z_R4_opr;
+  static LIR_Opr Z_R5_opr;
+  static LIR_Opr Z_R6_opr;
+  static LIR_Opr Z_R7_opr;
+  static LIR_Opr Z_R8_opr;
+  static LIR_Opr Z_R9_opr;
+  static LIR_Opr Z_R10_opr;
+  static LIR_Opr Z_R11_opr;
+  static LIR_Opr Z_R12_opr;
+  static LIR_Opr Z_R13_opr;
+  static LIR_Opr Z_R14_opr;
+  static LIR_Opr Z_R15_opr;
+
+  static LIR_Opr Z_R0_oop_opr;
+  static LIR_Opr Z_R1_oop_opr;
+  static LIR_Opr Z_R2_oop_opr;
+  static LIR_Opr Z_R3_oop_opr;
+  static LIR_Opr Z_R4_oop_opr;
+  static LIR_Opr Z_R5_oop_opr;
+  static LIR_Opr Z_R6_oop_opr;
+  static LIR_Opr Z_R7_oop_opr;
+  static LIR_Opr Z_R8_oop_opr;
+  static LIR_Opr Z_R9_oop_opr;
+  static LIR_Opr Z_R10_oop_opr;
+  static LIR_Opr Z_R11_oop_opr;
+  static LIR_Opr Z_R12_oop_opr;
+  static LIR_Opr Z_R13_oop_opr;
+  static LIR_Opr Z_R14_oop_opr;
+  static LIR_Opr Z_R15_oop_opr;
+
+  static LIR_Opr Z_R0_metadata_opr;
+  static LIR_Opr Z_R1_metadata_opr;
+  static LIR_Opr Z_R2_metadata_opr;
+  static LIR_Opr Z_R3_metadata_opr;
+  static LIR_Opr Z_R4_metadata_opr;
+  static LIR_Opr Z_R5_metadata_opr;
+  static LIR_Opr Z_R6_metadata_opr;
+  static LIR_Opr Z_R7_metadata_opr;
+  static LIR_Opr Z_R8_metadata_opr;
+  static LIR_Opr Z_R9_metadata_opr;
+  static LIR_Opr Z_R10_metadata_opr;
+  static LIR_Opr Z_R11_metadata_opr;
+  static LIR_Opr Z_R12_metadata_opr;
+  static LIR_Opr Z_R13_metadata_opr;
+  static LIR_Opr Z_R14_metadata_opr;
+  static LIR_Opr Z_R15_metadata_opr;
+
+  static LIR_Opr Z_SP_opr;
+  static LIR_Opr Z_FP_opr;
+
+  static LIR_Opr Z_R2_long_opr;
+  static LIR_Opr Z_R10_long_opr;
+  static LIR_Opr Z_R11_long_opr;
+
+  static LIR_Opr Z_F0_opr;
+  static LIR_Opr Z_F0_double_opr;
+
+ private:
+  static FloatRegister _fpu_rnr2reg [FrameMap::nof_fpu_regs]; // mapping c1 regnr. -> FloatRegister
+  static int           _fpu_reg2rnr [FrameMap::nof_fpu_regs]; // mapping assembler encoding -> c1 regnr.
+
+  static void map_float_register(int rnr, FloatRegister reg);
+
+  // FloatRegister -> c1 rnr
+  static int fpu_reg2rnr (FloatRegister reg) {
+    assert(_init_done, "tables not initialized");
+    int c1rnr = _fpu_reg2rnr[reg->encoding()];
+    debug_only(fpu_range_check(c1rnr);)
+    return c1rnr;
+  }
+
+ public:
+
+  static LIR_Opr as_long_opr(Register r) {
+    return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r));
+  }
+  static LIR_Opr as_pointer_opr(Register r) {
+    return LIR_OprFact::double_cpu(cpu_reg2rnr(r), cpu_reg2rnr(r));
+  }
+
+  static LIR_Opr as_float_opr(FloatRegister r) {
+    return LIR_OprFact::single_fpu(fpu_reg2rnr(r));
+  }
+  static LIR_Opr as_double_opr(FloatRegister r) {
+    return LIR_OprFact::double_fpu(fpu_reg2rnr(r));
+  }
+
+  static FloatRegister nr2floatreg (int rnr);
+
+  static VMReg fpu_regname (int n);
+
+  // No callee saved registers (saved values are not accessible if callee is in runtime).
+  static bool is_caller_save_register (LIR_Opr opr) { return true; }
+  static bool is_caller_save_register (Register r) { return true; }
+
+  static int nof_caller_save_cpu_regs() { return pd_nof_caller_save_cpu_regs_frame_map; }
+  static int last_cpu_reg()             { return pd_last_cpu_reg; }
+
+#endif // CPU_S390_VM_C1_FRAMEMAP_S390_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_LIRAssembler_s390.cpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,3037 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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 "precompiled.hpp"
+#include "c1/c1_Compilation.hpp"
+#include "c1/c1_LIRAssembler.hpp"
+#include "c1/c1_MacroAssembler.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "c1/c1_ValueStack.hpp"
+#include "ci/ciArrayKlass.hpp"
+#include "ci/ciInstance.hpp"
+#include "gc/shared/collectedHeap.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/cardTableModRefBS.hpp"
+#include "nativeInst_s390.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "vmreg_s390.inline.hpp"
+
+#define __ _masm->
+
+#ifndef PRODUCT
+#undef __
+#define __ (Verbose ? (_masm->block_comment(FILE_AND_LINE),_masm) : _masm)->
+#endif
+
+//------------------------------------------------------------
+
+bool LIR_Assembler::is_small_constant(LIR_Opr opr) {
+  // Not used on ZARCH_64
+  ShouldNotCallThis();
+  return false;
+}
+
+LIR_Opr LIR_Assembler::receiverOpr() {
+  return FrameMap::Z_R2_oop_opr;
+}
+
+LIR_Opr LIR_Assembler::osrBufferPointer() {
+  return FrameMap::Z_R2_opr;
+}
+
+int LIR_Assembler::initial_frame_size_in_bytes() const {
+  return in_bytes(frame_map()->framesize_in_bytes());
+}
+
+// Inline cache check: done before the frame is built.
+// The inline cached class is in Z_inline_cache(Z_R9).
+// We fetch the class of the receiver and compare it with the cached class.
+// If they do not match we jump to the slow case.
+int LIR_Assembler::check_icache() {
+  Register receiver = receiverOpr()->as_register();
+  int offset = __ offset();
+  __ inline_cache_check(receiver, Z_inline_cache);
+  return offset;
+}
+
+void LIR_Assembler::osr_entry() {
+  // On-stack-replacement entry sequence (interpreter frame layout described in interpreter_sparc.cpp):
+  //
+  //   1. Create a new compiled activation.
+  //   2. Initialize local variables in the compiled activation. The expression stack must be empty
+  //      at the osr_bci; it is not initialized.
+  //   3. Jump to the continuation address in compiled code to resume execution.
+
+  // OSR entry point
+  offsets()->set_value(CodeOffsets::OSR_Entry, code_offset());
+  BlockBegin* osr_entry = compilation()->hir()->osr_entry();
+  ValueStack* entry_state = osr_entry->end()->state();
+  int number_of_locks = entry_state->locks_size();
+
+  // Create a frame for the compiled activation.
+  __ build_frame(initial_frame_size_in_bytes(), bang_size_in_bytes());
+
+  // OSR buffer is
+  //
+  // locals[nlocals-1..0]
+  // monitors[number_of_locks-1..0]
+  //
+  // Locals is a direct copy of the interpreter frame so in the osr buffer
+  // the first slot in the local array is the last local from the interpreter
+  // and the last slot is local[0] (receiver) from the interpreter
+  //
+  // Similarly with locks. The first lock slot in the osr buffer is the nth lock
+  // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
+  // in the interpreter frame (the method lock if a sync method)
+
+  // Initialize monitors in the compiled activation.
+  //   I0: pointer to osr buffer
+  //
+  // All other registers are dead at this point and the locals will be
+  // copied into place by code emitted in the IR.
+
+  Register OSR_buf = osrBufferPointer()->as_register();
+  { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
+    int monitor_offset = BytesPerWord * method()->max_locals() +
+      (2 * BytesPerWord) * (number_of_locks - 1);
+    // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
+    // the OSR buffer using 2 word entries: first the lock and then
+    // the oop.
+    for (int i = 0; i < number_of_locks; i++) {
+      int slot_offset = monitor_offset - ((i * 2) * BytesPerWord);
+      // Verify the interpreter's monitor has a non-null object.
+      __ asm_assert_mem8_isnot_zero(slot_offset + 1*BytesPerWord, OSR_buf, "locked object is NULL", __LINE__);
+      // Copy the lock field into the compiled activation.
+      __ z_lg(Z_R1_scratch, slot_offset + 0, OSR_buf);
+      __ z_stg(Z_R1_scratch, frame_map()->address_for_monitor_lock(i));
+      __ z_lg(Z_R1_scratch, slot_offset + 1*BytesPerWord, OSR_buf);
+      __ z_stg(Z_R1_scratch, frame_map()->address_for_monitor_object(i));
+    }
+  }
+}
+
+// --------------------------------------------------------------------------------------------
+
+address LIR_Assembler::emit_call_c(address a) {
+  __ align_call_far_patchable(__ pc());
+  address call_addr = __ call_c_opt(a);
+  if (call_addr == NULL) {
+    bailout("const section overflow");
+  }
+  return call_addr;
+}
+
+int LIR_Assembler::emit_exception_handler() {
+  // If the last instruction is a call (typically to do a throw which
+  // is coming at the end after block reordering) the return address
+  // must still point into the code area in order to avoid assertion
+  // failures when searching for the corresponding bci. => Add a nop.
+  // (was bug 5/14/1999 - gri)
+  __ nop();
+
+  // Generate code for exception handler.
+  address handler_base = __ start_a_stub(exception_handler_size);
+  if (handler_base == NULL) {
+    // Not enough space left for the handler.
+    bailout("exception handler overflow");
+    return -1;
+  }
+
+  int offset = code_offset();
+
+  address a = Runtime1::entry_for (Runtime1::handle_exception_from_callee_id);
+  address call_addr = emit_call_c(a);
+  CHECK_BAILOUT_(-1);
+  __ should_not_reach_here();
+  guarantee(code_offset() - offset <= exception_handler_size, "overflow");
+  __ end_a_stub();
+
+  return offset;
+}
+
+// Emit the code to remove the frame from the stack in the exception
+// unwind path.
+int LIR_Assembler::emit_unwind_handler() {
+#ifndef PRODUCT
+  if (CommentedAssembly) {
+    _masm->block_comment("Unwind handler");
+  }
+#endif
+
+  int offset = code_offset();
+  Register exception_oop_callee_saved = Z_R10; // Z_R10 is callee-saved.
+  Register Rtmp1                      = Z_R11;
+  Register Rtmp2                      = Z_R12;
+
+  // Fetch the exception from TLS and clear out exception related thread state.
+  Address exc_oop_addr = Address(Z_thread, JavaThread::exception_oop_offset());
+  Address exc_pc_addr  = Address(Z_thread, JavaThread::exception_pc_offset());
+  __ z_lg(Z_EXC_OOP, exc_oop_addr);
+  __ clear_mem(exc_oop_addr, sizeof(oop));
+  __ clear_mem(exc_pc_addr, sizeof(intptr_t));
+
+  __ bind(_unwind_handler_entry);
+  __ verify_not_null_oop(Z_EXC_OOP);
+  if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
+    __ lgr_if_needed(exception_oop_callee_saved, Z_EXC_OOP); // Preserve the exception.
+  }
+
+  // Preform needed unlocking.
+  MonitorExitStub* stub = NULL;
+  if (method()->is_synchronized()) {
+    // Runtime1::monitorexit_id expects lock address in Z_R1_scratch.
+    LIR_Opr lock = FrameMap::as_opr(Z_R1_scratch);
+    monitor_address(0, lock);
+    stub = new MonitorExitStub(lock, true, 0);
+    __ unlock_object(Rtmp1, Rtmp2, lock->as_register(), *stub->entry());
+    __ bind(*stub->continuation());
+  }
+
+  if (compilation()->env()->dtrace_method_probes()) {
+    ShouldNotReachHere(); // Not supported.
+#if 0
+    __ mov(rdi, r15_thread);
+    __ mov_metadata(rsi, method()->constant_encoding());
+    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit)));
+#endif
+  }
+
+  if (method()->is_synchronized() || compilation()->env()->dtrace_method_probes()) {
+    __ lgr_if_needed(Z_EXC_OOP, exception_oop_callee_saved);  // Restore the exception.
+  }
+
+  // Remove the activation and dispatch to the unwind handler.
+  __ pop_frame();
+  __ z_lg(Z_EXC_PC, _z_abi16(return_pc), Z_SP);
+
+  // Z_EXC_OOP: exception oop
+  // Z_EXC_PC: exception pc
+
+  // Dispatch to the unwind logic.
+  __ load_const_optimized(Z_R5, Runtime1::entry_for (Runtime1::unwind_exception_id));
+  __ z_br(Z_R5);
+
+  // Emit the slow path assembly.
+  if (stub != NULL) {
+    stub->emit_code(this);
+  }
+
+  return offset;
+}
+
+int LIR_Assembler::emit_deopt_handler() {
+  // If the last instruction is a call (typically to do a throw which
+  // is coming at the end after block reordering) the return address
+  // must still point into the code area in order to avoid assertion
+  // failures when searching for the corresponding bci. => Add a nop.
+  // (was bug 5/14/1999 - gri)
+  __ nop();
+
+  // Generate code for exception handler.
+  address handler_base = __ start_a_stub(deopt_handler_size);
+  if (handler_base == NULL) {
+    // Not enough space left for the handler.
+    bailout("deopt handler overflow");
+    return -1;
+  }  int offset = code_offset();
+  // Size must be constant (see HandlerImpl::emit_deopt_handler).
+  __ load_const(Z_R1_scratch, SharedRuntime::deopt_blob()->unpack());
+  __ call(Z_R1_scratch);
+  guarantee(code_offset() - offset <= deopt_handler_size, "overflow");
+  __ end_a_stub();
+
+  return offset;
+}
+
+void LIR_Assembler::jobject2reg(jobject o, Register reg) {
+  if (o == NULL) {
+    __ clear_reg(reg, true/*64bit*/, false/*set cc*/); // Must not kill cc set by cmove.
+  } else {
+    AddressLiteral a = __ allocate_oop_address(o);
+    bool success = __ load_oop_from_toc(reg, a, reg);
+    if (!success) {
+      bailout("const section overflow");
+    }
+  }
+}
+
+void LIR_Assembler::jobject2reg_with_patching(Register reg, CodeEmitInfo *info) {
+  // Allocate a new index in table to hold the object once it's been patched.
+  int oop_index = __ oop_recorder()->allocate_oop_index(NULL);
+  PatchingStub* patch = new PatchingStub(_masm, patching_id(info), oop_index);
+
+  AddressLiteral addrlit((intptr_t)0, oop_Relocation::spec(oop_index));
+  assert(addrlit.rspec().type() == relocInfo::oop_type, "must be an oop reloc");
+  // The NULL will be dynamically patched later so the sequence to
+  // load the address literal must not be optimized.
+  __ load_const(reg, addrlit);
+
+  patching_epilog(patch, lir_patch_normal, reg, info);
+}
+
+void LIR_Assembler::metadata2reg(Metadata* md, Register reg) {
+  bool success = __ set_metadata_constant(md, reg);
+  if (!success) {
+    bailout("const section overflow");
+    return;
+  }
+}
+
+void LIR_Assembler::klass2reg_with_patching(Register reg, CodeEmitInfo *info) {
+  // Allocate a new index in table to hold the klass once it's been patched.
+  int index = __ oop_recorder()->allocate_metadata_index(NULL);
+  PatchingStub* patch = new PatchingStub(_masm, PatchingStub::load_klass_id, index);
+  AddressLiteral addrlit((intptr_t)0, metadata_Relocation::spec(index));
+  assert(addrlit.rspec().type() == relocInfo::metadata_type, "must be an metadata reloc");
+  // The NULL will be dynamically patched later so the sequence to
+  // load the address literal must not be optimized.
+  __ load_const(reg, addrlit);
+
+  patching_epilog(patch, lir_patch_normal, reg, info);
+}
+
+void LIR_Assembler::emit_op3(LIR_Op3* op) {
+  switch (op->code()) {
+    case lir_idiv:
+    case lir_irem:
+      arithmetic_idiv(op->code(),
+                      op->in_opr1(),
+                      op->in_opr2(),
+                      op->in_opr3(),
+                      op->result_opr(),
+                      op->info());
+      break;
+    default: ShouldNotReachHere(); break;
+  }
+}
+
+
+void LIR_Assembler::emit_opBranch(LIR_OpBranch* op) {
+#ifdef ASSERT
+  assert(op->block() == NULL || op->block()->label() == op->label(), "wrong label");
+  if (op->block() != NULL)  { _branch_target_blocks.append(op->block()); }
+  if (op->ublock() != NULL) { _branch_target_blocks.append(op->ublock()); }
+#endif
+
+  if (op->cond() == lir_cond_always) {
+    if (op->info() != NULL) { add_debug_info_for_branch(op->info()); }
+    __ branch_optimized(Assembler::bcondAlways, *(op->label()));
+  } else {
+    Assembler::branch_condition acond = Assembler::bcondZero;
+    if (op->code() == lir_cond_float_branch) {
+      assert(op->ublock() != NULL, "must have unordered successor");
+      __ branch_optimized(Assembler::bcondNotOrdered, *(op->ublock()->label()));
+    }
+    switch (op->cond()) {
+      case lir_cond_equal:        acond = Assembler::bcondEqual;     break;
+      case lir_cond_notEqual:     acond = Assembler::bcondNotEqual;  break;
+      case lir_cond_less:         acond = Assembler::bcondLow;       break;
+      case lir_cond_lessEqual:    acond = Assembler::bcondNotHigh;   break;
+      case lir_cond_greaterEqual: acond = Assembler::bcondNotLow;    break;
+      case lir_cond_greater:      acond = Assembler::bcondHigh;      break;
+      case lir_cond_belowEqual:   acond = Assembler::bcondNotHigh;   break;
+      case lir_cond_aboveEqual:   acond = Assembler::bcondNotLow;    break;
+      default:                         ShouldNotReachHere();
+    }
+    __ branch_optimized(acond,*(op->label()));
+  }
+}
+
+
+void LIR_Assembler::emit_opConvert(LIR_OpConvert* op) {
+  LIR_Opr src  = op->in_opr();
+  LIR_Opr dest = op->result_opr();
+
+  switch (op->bytecode()) {
+    case Bytecodes::_i2l:
+      __ move_reg_if_needed(dest->as_register_lo(), T_LONG, src->as_register(), T_INT);
+      break;
+
+    case Bytecodes::_l2i:
+      __ move_reg_if_needed(dest->as_register(), T_INT, src->as_register_lo(), T_LONG);
+      break;
+
+    case Bytecodes::_i2b:
+      __ move_reg_if_needed(dest->as_register(), T_BYTE, src->as_register(), T_INT);
+      break;
+
+    case Bytecodes::_i2c:
+      __ move_reg_if_needed(dest->as_register(), T_CHAR, src->as_register(), T_INT);
+      break;
+
+    case Bytecodes::_i2s:
+      __ move_reg_if_needed(dest->as_register(), T_SHORT, src->as_register(), T_INT);
+      break;
+
+    case Bytecodes::_f2d:
+      assert(dest->is_double_fpu(), "check");
+      __ move_freg_if_needed(dest->as_double_reg(), T_DOUBLE, src->as_float_reg(), T_FLOAT);
+      break;
+
+    case Bytecodes::_d2f:
+      assert(dest->is_single_fpu(), "check");
+      __ move_freg_if_needed(dest->as_float_reg(), T_FLOAT, src->as_double_reg(), T_DOUBLE);
+      break;
+
+    case Bytecodes::_i2f:
+      __ z_cefbr(dest->as_float_reg(), src->as_register());
+      break;
+
+    case Bytecodes::_i2d:
+      __ z_cdfbr(dest->as_double_reg(), src->as_register());
+      break;
+
+    case Bytecodes::_l2f:
+      __ z_cegbr(dest->as_float_reg(), src->as_register_lo());
+      break;
+    case Bytecodes::_l2d:
+      __ z_cdgbr(dest->as_double_reg(), src->as_register_lo());
+      break;
+
+    case Bytecodes::_f2i:
+    case Bytecodes::_f2l: {
+      Label done;
+      FloatRegister Rsrc = src->as_float_reg();
+      Register Rdst = (op->bytecode() == Bytecodes::_f2i ? dest->as_register() : dest->as_register_lo());
+      __ clear_reg(Rdst, true, false);
+      __ z_cebr(Rsrc, Rsrc);
+      __ z_brno(done); // NaN -> 0
+      if (op->bytecode() == Bytecodes::_f2i) {
+        __ z_cfebr(Rdst, Rsrc, Assembler::to_zero);
+      } else { // op->bytecode() == Bytecodes::_f2l
+        __ z_cgebr(Rdst, Rsrc, Assembler::to_zero);
+      }
+      __ bind(done);
+    }
+    break;
+
+    case Bytecodes::_d2i:
+    case Bytecodes::_d2l: {
+      Label done;
+      FloatRegister Rsrc = src->as_double_reg();
+      Register Rdst = (op->bytecode() == Bytecodes::_d2i ? dest->as_register() : dest->as_register_lo());
+      __ clear_reg(Rdst, true, false);  // Don't set CC.
+      __ z_cdbr(Rsrc, Rsrc);
+      __ z_brno(done); // NaN -> 0
+      if (op->bytecode() == Bytecodes::_d2i) {
+        __ z_cfdbr(Rdst, Rsrc, Assembler::to_zero);
+      } else { // Bytecodes::_d2l
+        __ z_cgdbr(Rdst, Rsrc, Assembler::to_zero);
+      }
+      __ bind(done);
+    }
+    break;
+
+    default: ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::align_call(LIR_Code code) {
+  // End of call instruction must be 4 byte aligned.
+  int offset = __ offset();
+  switch (code) {
+    case lir_icvirtual_call:
+      offset += MacroAssembler::load_const_from_toc_size();
+      // no break
+    case lir_static_call:
+    case lir_optvirtual_call:
+    case lir_dynamic_call:
+      offset += NativeCall::call_far_pcrelative_displacement_offset;
+      break;
+    case lir_virtual_call:   // currently, sparc-specific for niagara
+    default: ShouldNotReachHere();
+  }
+  if ((offset & (NativeCall::call_far_pcrelative_displacement_alignment-1)) != 0) {
+    __ nop();
+  }
+}
+
+void LIR_Assembler::call(LIR_OpJavaCall* op, relocInfo::relocType rtype) {
+  assert((__ offset() + NativeCall::call_far_pcrelative_displacement_offset) % NativeCall::call_far_pcrelative_displacement_alignment == 0,
+         "must be aligned (offset=%d)", __ offset());
+  assert(rtype == relocInfo::none ||
+         rtype == relocInfo::opt_virtual_call_type ||
+         rtype == relocInfo::static_call_type, "unexpected rtype");
+  // Prepend each BRASL with a nop.
+  __ relocate(rtype);
+  __ z_nop();
+  __ z_brasl(Z_R14, op->addr());
+  add_call_info(code_offset(), op->info());
+}
+
+void LIR_Assembler::ic_call(LIR_OpJavaCall* op) {
+  address virtual_call_oop_addr = NULL;
+  AddressLiteral empty_ic((address) Universe::non_oop_word());
+  virtual_call_oop_addr = __ pc();
+  bool success = __ load_const_from_toc(Z_inline_cache, empty_ic);
+  if (!success) {
+    bailout("const section overflow");
+    return;
+  }
+
+  // CALL to fixup routine. Fixup routine uses ScopeDesc info
+  // to determine who we intended to call.
+  __ relocate(virtual_call_Relocation::spec(virtual_call_oop_addr));
+  call(op, relocInfo::none);
+}
+
+// not supported
+void LIR_Assembler::vtable_call(LIR_OpJavaCall* op) {
+  ShouldNotReachHere();
+}
+
+void LIR_Assembler::move_regs(Register from_reg, Register to_reg) {
+  if (from_reg != to_reg) __ z_lgr(to_reg, from_reg);
+}
+
+void LIR_Assembler::const2stack(LIR_Opr src, LIR_Opr dest) {
+  assert(src->is_constant(), "should not call otherwise");
+  assert(dest->is_stack(), "should not call otherwise");
+  LIR_Const* c = src->as_constant_ptr();
+
+  unsigned int lmem = 0;
+  unsigned int lcon = 0;
+  int64_t cbits = 0;
+  Address dest_addr;
+  switch (c->type()) {
+    case T_INT:  // fall through
+    case T_FLOAT:
+      dest_addr = frame_map()->address_for_slot(dest->single_stack_ix());
+      lmem = 4; lcon = 4; cbits = c->as_jint_bits();
+      break;
+
+    case T_ADDRESS:
+      dest_addr = frame_map()->address_for_slot(dest->single_stack_ix());
+      lmem = 8; lcon = 4; cbits = c->as_jint_bits();
+      break;
+
+    case T_OBJECT:
+      dest_addr = frame_map()->address_for_slot(dest->single_stack_ix());
+      if (c->as_jobject() == NULL) {
+        __ store_const(dest_addr, (int64_t)NULL_WORD, 8, 8);
+      } else {
+        jobject2reg(c->as_jobject(), Z_R1_scratch);
+        __ reg2mem_opt(Z_R1_scratch, dest_addr, true);
+      }
+      return;
+
+    case T_LONG:  // fall through
+    case T_DOUBLE:
+      dest_addr = frame_map()->address_for_slot(dest->double_stack_ix());
+      lmem = 8; lcon = 8; cbits = (int64_t)(c->as_jlong_bits());
+      break;
+
+    default:
+      ShouldNotReachHere();
+  }
+
+  __ store_const(dest_addr, cbits, lmem, lcon);
+}
+
+void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) {
+  assert(src->is_constant(), "should not call otherwise");
+  assert(dest->is_address(), "should not call otherwise");
+  // See special case in LIRGenerator::do_StoreIndexed.
+  // T_BYTE: Special case for card mark store.
+  assert(type == T_BYTE || !dest->as_address_ptr()->index()->is_valid(), "not supported");
+  LIR_Const* c = src->as_constant_ptr();
+  Address addr = as_Address(dest->as_address_ptr());
+
+  int store_offset = -1;
+  unsigned int lmem = 0;
+  unsigned int lcon = 0;
+  int64_t cbits = 0;
+  switch (type) {
+    case T_INT:    // fall through
+    case T_FLOAT:
+      lmem = 4; lcon = 4; cbits = c->as_jint_bits();
+      break;
+
+    case T_ADDRESS:
+      lmem = 8; lcon = 4; cbits = c->as_jint_bits();
+      break;
+
+    case T_OBJECT:  // fall through
+    case T_ARRAY:
+      if (c->as_jobject() == NULL) {
+        if (UseCompressedOops && !wide) {
+          store_offset = __ store_const(addr, (int32_t)NULL_WORD, 4, 4);
+        } else {
+          store_offset = __ store_const(addr, (int64_t)NULL_WORD, 8, 8);
+        }
+      } else {
+        jobject2reg(c->as_jobject(), Z_R1_scratch);
+        if (UseCompressedOops && !wide) {
+          __ encode_heap_oop(Z_R1_scratch);
+          store_offset = __ reg2mem_opt(Z_R1_scratch, addr, false);
+        } else {
+          store_offset = __ reg2mem_opt(Z_R1_scratch, addr, true);
+        }
+      }
+      assert(store_offset >= 0, "check");
+      break;
+
+    case T_LONG:    // fall through
+    case T_DOUBLE:
+      lmem = 8; lcon = 8; cbits = (int64_t)(c->as_jlong_bits());
+      break;
+
+    case T_BOOLEAN: // fall through
+    case T_BYTE:
+      lmem = 1; lcon = 1; cbits = (int8_t)(c->as_jint());
+      break;
+
+    case T_CHAR:    // fall through
+    case T_SHORT:
+      lmem = 2; lcon = 2; cbits = (int16_t)(c->as_jint());
+      break;
+
+    default:
+      ShouldNotReachHere();
+  };
+
+  // Index register is normally not supported, but for
+  // LIRGenerator::CardTableModRef_post_barrier we make an exception.
+  if (type == T_BYTE && dest->as_address_ptr()->index()->is_valid()) {
+    __ load_const_optimized(Z_R0_scratch, (int8_t)(c->as_jint()));
+    store_offset = __ offset();
+    if (Immediate::is_uimm12(addr.disp())) {
+      __ z_stc(Z_R0_scratch, addr);
+    } else {
+      __ z_stcy(Z_R0_scratch, addr);
+    }
+  }
+
+  if (store_offset == -1) {
+    store_offset = __ store_const(addr, cbits, lmem, lcon);
+    assert(store_offset >= 0, "check");
+  }
+
+  if (info != NULL) {
+    add_debug_info_for_null_check(store_offset, info);
+  }
+}
+
+void LIR_Assembler::const2reg(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+  assert(src->is_constant(), "should not call otherwise");
+  assert(dest->is_register(), "should not call otherwise");
+  LIR_Const* c = src->as_constant_ptr();
+
+  switch (c->type()) {
+    case T_INT: {
+      assert(patch_code == lir_patch_none, "no patching handled here");
+      __ load_const_optimized(dest->as_register(), c->as_jint());
+      break;
+    }
+
+    case T_ADDRESS: {
+      assert(patch_code == lir_patch_none, "no patching handled here");
+      __ load_const_optimized(dest->as_register(), c->as_jint());
+      break;
+    }
+
+    case T_LONG: {
+      assert(patch_code == lir_patch_none, "no patching handled here");
+      __ load_const_optimized(dest->as_register_lo(), (intptr_t)c->as_jlong());
+      break;
+    }
+
+    case T_OBJECT: {
+      if (patch_code != lir_patch_none) {
+        jobject2reg_with_patching(dest->as_register(), info);
+      } else {
+        jobject2reg(c->as_jobject(), dest->as_register());
+      }
+      break;
+    }
+
+    case T_METADATA: {
+      if (patch_code != lir_patch_none) {
+        klass2reg_with_patching(dest->as_register(), info);
+      } else {
+        metadata2reg(c->as_metadata(), dest->as_register());
+      }
+      break;
+    }
+
+    case T_FLOAT: {
+      Register toc_reg = Z_R1_scratch;
+      __ load_toc(toc_reg);
+      address const_addr = __ float_constant(c->as_jfloat());
+      if (const_addr == NULL) {
+        bailout("const section overflow");
+        break;
+      }
+      int displ = const_addr - _masm->code()->consts()->start();
+      if (dest->is_single_fpu()) {
+        __ z_ley(dest->as_float_reg(), displ, toc_reg);
+      } else {
+        assert(dest->is_single_cpu(), "Must be a cpu register.");
+        __ z_ly(dest->as_register(), displ, toc_reg);
+      }
+    }
+    break;
+
+    case T_DOUBLE: {
+      Register toc_reg = Z_R1_scratch;
+      __ load_toc(toc_reg);
+      address const_addr = __ double_constant(c->as_jdouble());
+      if (const_addr == NULL) {
+        bailout("const section overflow");
+        break;
+      }
+      int displ = const_addr - _masm->code()->consts()->start();
+      if (dest->is_double_fpu()) {
+        __ z_ldy(dest->as_double_reg(), displ, toc_reg);
+      } else {
+        assert(dest->is_double_cpu(), "Must be a long register.");
+        __ z_lg(dest->as_register_lo(), displ, toc_reg);
+      }
+    }
+    break;
+
+    default:
+      ShouldNotReachHere();
+  }
+}
+
+Address LIR_Assembler::as_Address(LIR_Address* addr) {
+  if (addr->base()->is_illegal()) {
+    Unimplemented();
+  }
+
+  Register base = addr->base()->as_pointer_register();
+
+  if (addr->index()->is_illegal()) {
+    return Address(base, addr->disp());
+  } else if (addr->index()->is_cpu_register()) {
+    Register index = addr->index()->as_pointer_register();
+    return Address(base, index, addr->disp());
+  } else if (addr->index()->is_constant()) {
+    intptr_t addr_offset = addr->index()->as_constant_ptr()->as_jint() + addr->disp();
+    return Address(base, addr_offset);
+  } else {
+    ShouldNotReachHere();
+    return Address();
+  }
+}
+
+void LIR_Assembler::stack2stack(LIR_Opr src, LIR_Opr dest, BasicType type) {
+  switch (type) {
+    case T_INT:
+    case T_FLOAT: {
+      Register tmp = Z_R1_scratch;
+      Address from = frame_map()->address_for_slot(src->single_stack_ix());
+      Address to   = frame_map()->address_for_slot(dest->single_stack_ix());
+      __ mem2reg_opt(tmp, from, false);
+      __ reg2mem_opt(tmp, to, false);
+      break;
+    }
+    case T_ADDRESS:
+    case T_OBJECT: {
+      Register tmp = Z_R1_scratch;
+      Address from = frame_map()->address_for_slot(src->single_stack_ix());
+      Address to   = frame_map()->address_for_slot(dest->single_stack_ix());
+      __ mem2reg_opt(tmp, from, true);
+      __ reg2mem_opt(tmp, to, true);
+      break;
+    }
+    case T_LONG:
+    case T_DOUBLE: {
+      Register tmp = Z_R1_scratch;
+      Address from = frame_map()->address_for_double_slot(src->double_stack_ix());
+      Address to   = frame_map()->address_for_double_slot(dest->double_stack_ix());
+      __ mem2reg_opt(tmp, from, true);
+      __ reg2mem_opt(tmp, to, true);
+      break;
+    }
+
+    default:
+      ShouldNotReachHere();
+  }
+}
+
+// 4-byte accesses only! Don't use it to access 8 bytes!
+Address LIR_Assembler::as_Address_hi(LIR_Address* addr) {
+  ShouldNotCallThis();
+  return 0; // unused
+}
+
+// 4-byte accesses only! Don't use it to access 8 bytes!
+Address LIR_Assembler::as_Address_lo(LIR_Address* addr) {
+  ShouldNotCallThis();
+  return 0; // unused
+}
+
+void LIR_Assembler::mem2reg(LIR_Opr src_opr, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code,
+                            CodeEmitInfo* info, bool wide, bool unaligned) {
+
+  assert(type != T_METADATA, "load of metadata ptr not supported");
+  LIR_Address* addr = src_opr->as_address_ptr();
+  LIR_Opr to_reg = dest;
+
+  Register src = addr->base()->as_pointer_register();
+  Register disp_reg = Z_R0;
+  int disp_value = addr->disp();
+  bool needs_patching = (patch_code != lir_patch_none);
+
+  if (addr->base()->type() == T_OBJECT) {
+    __ verify_oop(src);
+  }
+
+  PatchingStub* patch = NULL;
+  if (needs_patching) {
+    patch = new PatchingStub(_masm, PatchingStub::access_field_id);
+    assert(!to_reg->is_double_cpu() ||
+           patch_code == lir_patch_none ||
+           patch_code == lir_patch_normal, "patching doesn't match register");
+  }
+
+  if (addr->index()->is_illegal()) {
+    if (!Immediate::is_simm20(disp_value)) {
+      if (needs_patching) {
+        __ load_const(Z_R1_scratch, (intptr_t)0);
+      } else {
+        __ load_const_optimized(Z_R1_scratch, disp_value);
+      }
+      disp_reg = Z_R1_scratch;
+      disp_value = 0;
+    }
+  } else {
+    if (!Immediate::is_simm20(disp_value)) {
+      __ load_const_optimized(Z_R1_scratch, disp_value);
+      __ z_la(Z_R1_scratch, 0, Z_R1_scratch, addr->index()->as_register());
+      disp_reg = Z_R1_scratch;
+      disp_value = 0;
+    }
+    disp_reg = addr->index()->as_pointer_register();
+  }
+
+  // Remember the offset of the load. The patching_epilog must be done
+  // before the call to add_debug_info, otherwise the PcDescs don't get
+  // entered in increasing order.
+  int offset = code_offset();
+
+  assert(disp_reg != Z_R0 || Immediate::is_simm20(disp_value), "should have set this up");
+
+  bool short_disp = Immediate::is_uimm12(disp_value);
+
+  switch (type) {
+    case T_BOOLEAN: // fall through
+    case T_BYTE  :  __ z_lb(dest->as_register(),   disp_value, disp_reg, src); break;
+    case T_CHAR  :  __ z_llgh(dest->as_register(), disp_value, disp_reg, src); break;
+    case T_SHORT :
+      if (short_disp) {
+                    __ z_lh(dest->as_register(),   disp_value, disp_reg, src);
+      } else {
+                    __ z_lhy(dest->as_register(),  disp_value, disp_reg, src);
+      }
+      break;
+    case T_INT   :
+      if (short_disp) {
+                    __ z_l(dest->as_register(),    disp_value, disp_reg, src);
+      } else {
+                    __ z_ly(dest->as_register(),   disp_value, disp_reg, src);
+      }
+      break;
+    case T_ADDRESS:
+      if (UseCompressedClassPointers && addr->disp() == oopDesc::klass_offset_in_bytes()) {
+        __ z_llgf(dest->as_register(), disp_value, disp_reg, src);
+        __ decode_klass_not_null(dest->as_register());
+      } else {
+        __ z_lg(dest->as_register(), disp_value, disp_reg, src);
+      }
+      break;
+    case T_ARRAY : // fall through
+    case T_OBJECT:
+    {
+      if (UseCompressedOops && !wide) {
+        __ z_llgf(dest->as_register(), disp_value, disp_reg, src);
+        __ oop_decoder(dest->as_register(), dest->as_register(), true);
+      } else {
+        __ z_lg(dest->as_register(), disp_value, disp_reg, src);
+      }
+      break;
+    }
+    case T_FLOAT:
+      if (short_disp) {
+                    __ z_le(dest->as_float_reg(),  disp_value, disp_reg, src);
+      } else {
+                    __ z_ley(dest->as_float_reg(), disp_value, disp_reg, src);
+      }
+      break;
+    case T_DOUBLE:
+      if (short_disp) {
+                    __ z_ld(dest->as_double_reg(),  disp_value, disp_reg, src);
+      } else {
+                    __ z_ldy(dest->as_double_reg(), disp_value, disp_reg, src);
+      }
+      break;
+    case T_LONG  :  __ z_lg(dest->as_register_lo(), disp_value, disp_reg, src); break;
+    default      : ShouldNotReachHere();
+  }
+  if (type == T_ARRAY || type == T_OBJECT) {
+    __ verify_oop(dest->as_register());
+  }
+
+  if (patch != NULL) {
+    patching_epilog(patch, patch_code, src, info);
+  }
+  if (info != NULL) add_debug_info_for_null_check(offset, info);
+}
+
+void LIR_Assembler::stack2reg(LIR_Opr src, LIR_Opr dest, BasicType type) {
+  assert(src->is_stack(), "should not call otherwise");
+  assert(dest->is_register(), "should not call otherwise");
+
+  if (dest->is_single_cpu()) {
+    if (type == T_ARRAY || type == T_OBJECT) {
+      __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true);
+      __ verify_oop(dest->as_register());
+    } else if (type == T_METADATA) {
+      __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), true);
+    } else {
+      __ mem2reg_opt(dest->as_register(), frame_map()->address_for_slot(src->single_stack_ix()), false);
+    }
+  } else if (dest->is_double_cpu()) {
+    Address src_addr_LO = frame_map()->address_for_slot(src->double_stack_ix());
+    __ mem2reg_opt(dest->as_register_lo(), src_addr_LO, true);
+  } else if (dest->is_single_fpu()) {
+    Address src_addr = frame_map()->address_for_slot(src->single_stack_ix());
+    __ mem2freg_opt(dest->as_float_reg(), src_addr, false);
+  } else if (dest->is_double_fpu()) {
+    Address src_addr = frame_map()->address_for_slot(src->double_stack_ix());
+    __ mem2freg_opt(dest->as_double_reg(), src_addr, true);
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::reg2stack(LIR_Opr src, LIR_Opr dest, BasicType type, bool pop_fpu_stack) {
+  assert(src->is_register(), "should not call otherwise");
+  assert(dest->is_stack(), "should not call otherwise");
+
+  if (src->is_single_cpu()) {
+    const Address dst = frame_map()->address_for_slot(dest->single_stack_ix());
+    if (type == T_OBJECT || type == T_ARRAY) {
+      __ verify_oop(src->as_register());
+      __ reg2mem_opt(src->as_register(), dst, true);
+    } else if (type == T_METADATA) {
+      __ reg2mem_opt(src->as_register(), dst, true);
+    } else {
+      __ reg2mem_opt(src->as_register(), dst, false);
+    }
+  } else if (src->is_double_cpu()) {
+    Address dstLO = frame_map()->address_for_slot(dest->double_stack_ix());
+    __ reg2mem_opt(src->as_register_lo(), dstLO, true);
+  } else if (src->is_single_fpu()) {
+    Address dst_addr = frame_map()->address_for_slot(dest->single_stack_ix());
+    __ freg2mem_opt(src->as_float_reg(), dst_addr, false);
+  } else if (src->is_double_fpu()) {
+    Address dst_addr = frame_map()->address_for_slot(dest->double_stack_ix());
+    __ freg2mem_opt(src->as_double_reg(), dst_addr, true);
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::reg2reg(LIR_Opr from_reg, LIR_Opr to_reg) {
+  if (from_reg->is_float_kind() && to_reg->is_float_kind()) {
+    if (from_reg->is_double_fpu()) {
+      // double to double moves
+      assert(to_reg->is_double_fpu(), "should match");
+      __ z_ldr(to_reg->as_double_reg(), from_reg->as_double_reg());
+    } else {
+      // float to float moves
+      assert(to_reg->is_single_fpu(), "should match");
+      __ z_ler(to_reg->as_float_reg(), from_reg->as_float_reg());
+    }
+  } else if (!from_reg->is_float_kind() && !to_reg->is_float_kind()) {
+    if (from_reg->is_double_cpu()) {
+      __ z_lgr(to_reg->as_pointer_register(), from_reg->as_pointer_register());
+    } else if (to_reg->is_double_cpu()) {
+      // int to int moves
+      __ z_lgr(to_reg->as_register_lo(), from_reg->as_register());
+    } else {
+      // int to int moves
+      __ z_lgr(to_reg->as_register(), from_reg->as_register());
+    }
+  } else {
+    ShouldNotReachHere();
+  }
+  if (to_reg->type() == T_OBJECT || to_reg->type() == T_ARRAY) {
+    __ verify_oop(to_reg->as_register());
+  }
+}
+
+void LIR_Assembler::reg2mem(LIR_Opr from, LIR_Opr dest_opr, BasicType type,
+                            LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack,
+                            bool wide, bool unaligned) {
+  assert(type != T_METADATA, "store of metadata ptr not supported");
+  LIR_Address* addr = dest_opr->as_address_ptr();
+
+  Register dest = addr->base()->as_pointer_register();
+  Register disp_reg = Z_R0;
+  int disp_value = addr->disp();
+  bool needs_patching = (patch_code != lir_patch_none);
+
+  if (addr->base()->is_oop_register()) {
+    __ verify_oop(dest);
+  }
+
+  PatchingStub* patch = NULL;
+  if (needs_patching) {
+    patch = new PatchingStub(_masm, PatchingStub::access_field_id);
+    assert(!from->is_double_cpu() ||
+           patch_code == lir_patch_none ||
+           patch_code == lir_patch_normal, "patching doesn't match register");
+  }
+
+  assert(!needs_patching || (!Immediate::is_simm20(disp_value) && addr->index()->is_illegal()), "assumption");
+  if (addr->index()->is_illegal()) {
+    if (!Immediate::is_simm20(disp_value)) {
+      if (needs_patching) {
+        __ load_const(Z_R1_scratch, (intptr_t)0);
+      } else {
+        __ load_const_optimized(Z_R1_scratch, disp_value);
+      }
+      disp_reg = Z_R1_scratch;
+      disp_value = 0;
+    }
+  } else {
+    if (!Immediate::is_simm20(disp_value)) {
+      __ load_const_optimized(Z_R1_scratch, disp_value);
+      __ z_la(Z_R1_scratch, 0, Z_R1_scratch, addr->index()->as_register());
+      disp_reg = Z_R1_scratch;
+      disp_value = 0;
+    }
+    disp_reg = addr->index()->as_pointer_register();
+  }
+
+  assert(disp_reg != Z_R0 || Immediate::is_simm20(disp_value), "should have set this up");
+
+  if (type == T_ARRAY || type == T_OBJECT) {
+    __ verify_oop(from->as_register());
+  }
+
+  bool short_disp = Immediate::is_uimm12(disp_value);
+
+  // Remember the offset of the store. The patching_epilog must be done
+  // before the call to add_debug_info_for_null_check, otherwise the PcDescs don't get
+  // entered in increasing order.
+  int offset = code_offset();
+  switch (type) {
+    case T_BOOLEAN: // fall through
+    case T_BYTE  :
+      if (short_disp) {
+                    __ z_stc(from->as_register(),  disp_value, disp_reg, dest);
+      } else {
+                    __ z_stcy(from->as_register(), disp_value, disp_reg, dest);
+      }
+      break;
+    case T_CHAR  : // fall through
+    case T_SHORT :
+      if (short_disp) {
+                    __ z_sth(from->as_register(),  disp_value, disp_reg, dest);
+      } else {
+                    __ z_sthy(from->as_register(), disp_value, disp_reg, dest);
+      }
+      break;
+    case T_INT   :
+      if (short_disp) {
+                    __ z_st(from->as_register(),  disp_value, disp_reg, dest);
+      } else {
+                    __ z_sty(from->as_register(), disp_value, disp_reg, dest);
+      }
+      break;
+    case T_LONG  :  __ z_stg(from->as_register_lo(), disp_value, disp_reg, dest); break;
+    case T_ADDRESS: __ z_stg(from->as_register(),    disp_value, disp_reg, dest); break;
+      break;
+    case T_ARRAY : // fall through
+    case T_OBJECT:
+      {
+        if (UseCompressedOops && !wide) {
+          Register compressed_src = Z_R14;
+          __ z_lgr(compressed_src, from->as_register());
+          __ encode_heap_oop(compressed_src);
+          offset = code_offset();
+          if (short_disp) {
+            __ z_st(compressed_src,  disp_value, disp_reg, dest);
+          } else {
+            __ z_sty(compressed_src, disp_value, disp_reg, dest);
+          }
+        } else {
+          __ z_stg(from->as_register(), disp_value, disp_reg, dest);
+        }
+        break;
+      }
+    case T_FLOAT :
+      if (short_disp) {
+                    __ z_ste(from->as_float_reg(),  disp_value, disp_reg, dest);
+      } else {
+                    __ z_stey(from->as_float_reg(), disp_value, disp_reg, dest);
+      }
+      break;
+    case T_DOUBLE:
+      if (short_disp) {
+                    __ z_std(from->as_double_reg(),  disp_value, disp_reg, dest);
+      } else {
+                    __ z_stdy(from->as_double_reg(), disp_value, disp_reg, dest);
+      }
+      break;
+    default: ShouldNotReachHere();
+  }
+
+  if (patch != NULL) {
+    patching_epilog(patch, patch_code, dest, info);
+  }
+
+  if (info != NULL) add_debug_info_for_null_check(offset, info);
+}
+
+
+void LIR_Assembler::return_op(LIR_Opr result) {
+  assert(result->is_illegal() ||
+         (result->is_single_cpu() && result->as_register() == Z_R2) ||
+         (result->is_double_cpu() && result->as_register_lo() == Z_R2) ||
+         (result->is_single_fpu() && result->as_float_reg() == Z_F0) ||
+         (result->is_double_fpu() && result->as_double_reg() == Z_F0), "convention");
+
+  AddressLiteral pp(os::get_polling_page());
+  __ load_const_optimized(Z_R1_scratch, pp);
+
+  // Pop the frame before the safepoint code.
+  int retPC_offset = initial_frame_size_in_bytes() + _z_abi16(return_pc);
+  if (Displacement::is_validDisp(retPC_offset)) {
+    __ z_lg(Z_R14, retPC_offset, Z_SP);
+    __ add2reg(Z_SP, initial_frame_size_in_bytes());
+  } else {
+    __ add2reg(Z_SP, initial_frame_size_in_bytes());
+    __ restore_return_pc();
+  }
+
+  // We need to mark the code position where the load from the safepoint
+  // polling page was emitted as relocInfo::poll_return_type here.
+  __ relocate(relocInfo::poll_return_type);
+  __ load_from_polling_page(Z_R1_scratch);
+
+  __ z_br(Z_R14); // Return to caller.
+}
+
+int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
+  AddressLiteral pp(os::get_polling_page());
+  __ load_const_optimized(tmp->as_register_lo(), pp);
+  guarantee(info != NULL, "Shouldn't be NULL");
+  add_debug_info_for_branch(info);
+  int offset = __ offset();
+  __ relocate(relocInfo::poll_type);
+  __ load_from_polling_page(tmp->as_register_lo());
+  return offset;
+}
+
+void LIR_Assembler::emit_static_call_stub() {
+
+  // Stub is fixed up when the corresponding call is converted from calling
+  // compiled code to calling interpreted code.
+
+  address call_pc = __ pc();
+  address stub = __ start_a_stub(call_stub_size);
+  if (stub == NULL) {
+    bailout("static call stub overflow");
+    return;
+  }
+
+  int start = __ offset();
+
+  __ relocate(static_stub_Relocation::spec(call_pc));
+
+  // See also Matcher::interpreter_method_oop_reg().
+  AddressLiteral meta = __ allocate_metadata_address(NULL);
+  bool success = __ load_const_from_toc(Z_method, meta);
+
+  __ set_inst_mark();
+  AddressLiteral a((address)-1);
+  success = success && __ load_const_from_toc(Z_R1, a);
+  if (!success) {
+    bailout("const section overflow");
+    return;
+  }
+
+  __ z_br(Z_R1);
+  assert(__ offset() - start <= call_stub_size, "stub too big");
+  __ end_a_stub(); // Update current stubs pointer and restore insts_end.
+}
+
+void LIR_Assembler::comp_op(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Op2* op) {
+  bool unsigned_comp = condition == lir_cond_belowEqual || condition == lir_cond_aboveEqual;
+  if (opr1->is_single_cpu()) {
+    Register reg1 = opr1->as_register();
+    if (opr2->is_single_cpu()) {
+      // cpu register - cpu register
+      if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
+        __ z_clgr(reg1, opr2->as_register());
+      } else {
+        assert(opr2->type() != T_OBJECT && opr2->type() != T_ARRAY, "cmp int, oop?");
+        if (unsigned_comp) {
+          __ z_clr(reg1, opr2->as_register());
+        } else {
+          __ z_cr(reg1, opr2->as_register());
+        }
+      }
+    } else if (opr2->is_stack()) {
+      // cpu register - stack
+      if (opr1->type() == T_OBJECT || opr1->type() == T_ARRAY) {
+        __ z_cg(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
+      } else {
+        if (unsigned_comp) {
+          __ z_cly(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
+        } else {
+          __ z_cy(reg1, frame_map()->address_for_slot(opr2->single_stack_ix()));
+        }
+      }
+    } else if (opr2->is_constant()) {
+      // cpu register - constant
+      LIR_Const* c = opr2->as_constant_ptr();
+      if (c->type() == T_INT) {
+        if (unsigned_comp) {
+          __ z_clfi(reg1, c->as_jint());
+        } else {
+          __ z_cfi(reg1, c->as_jint());
+        }
+      } else if (c->type() == T_OBJECT || c->type() == T_ARRAY) {
+        // In 64bit oops are single register.
+        jobject o = c->as_jobject();
+        if (o == NULL) {
+          __ z_ltgr(reg1, reg1);
+        } else {
+          jobject2reg(o, Z_R1_scratch);
+          __ z_cgr(reg1, Z_R1_scratch);
+        }
+      } else {
+        fatal("unexpected type: %s", basictype_to_str(c->type()));
+      }
+      // cpu register - address
+    } else if (opr2->is_address()) {
+      if (op->info() != NULL) {
+        add_debug_info_for_null_check_here(op->info());
+      }
+      if (unsigned_comp) {
+        __ z_cly(reg1, as_Address(opr2->as_address_ptr()));
+      } else {
+        __ z_cy(reg1, as_Address(opr2->as_address_ptr()));
+      }
+    } else {
+      ShouldNotReachHere();
+    }
+
+  } else if (opr1->is_double_cpu()) {
+    assert(!unsigned_comp, "unexpected");
+    Register xlo = opr1->as_register_lo();
+    Register xhi = opr1->as_register_hi();
+    if (opr2->is_double_cpu()) {
+      __ z_cgr(xlo, opr2->as_register_lo());
+    } else if (opr2->is_constant()) {
+      // cpu register - constant 0
+      assert(opr2->as_jlong() == (jlong)0, "only handles zero");
+      __ z_ltgr(xlo, xlo);
+    } else {
+      ShouldNotReachHere();
+    }
+
+  } else if (opr1->is_single_fpu()) {
+    if (opr2->is_single_fpu()) {
+      __ z_cebr(opr1->as_float_reg(), opr2->as_float_reg());
+    } else {
+      // stack slot
+      Address addr = frame_map()->address_for_slot(opr2->single_stack_ix());
+      if (Immediate::is_uimm12(addr.disp())) {
+        __ z_ceb(opr1->as_float_reg(), addr);
+      } else {
+        __ z_ley(Z_fscratch_1, addr);
+        __ z_cebr(opr1->as_float_reg(), Z_fscratch_1);
+      }
+    }
+  } else if (opr1->is_double_fpu()) {
+    if (opr2->is_double_fpu()) {
+    __ z_cdbr(opr1->as_double_reg(), opr2->as_double_reg());
+    } else {
+      // stack slot
+      Address addr = frame_map()->address_for_slot(opr2->double_stack_ix());
+      if (Immediate::is_uimm12(addr.disp())) {
+        __ z_cdb(opr1->as_double_reg(), addr);
+      } else {
+        __ z_ldy(Z_fscratch_1, addr);
+        __ z_cdbr(opr1->as_double_reg(), Z_fscratch_1);
+      }
+    }
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst, LIR_Op2* op) {
+  Label    done;
+  Register dreg = dst->as_register();
+
+  if (code == lir_cmp_fd2i || code == lir_ucmp_fd2i) {
+    assert((left->is_single_fpu() && right->is_single_fpu()) ||
+           (left->is_double_fpu() && right->is_double_fpu()), "unexpected operand types");
+    bool is_single = left->is_single_fpu();
+    bool is_unordered_less = (code == lir_ucmp_fd2i);
+    FloatRegister lreg = is_single ? left->as_float_reg() : left->as_double_reg();
+    FloatRegister rreg = is_single ? right->as_float_reg() : right->as_double_reg();
+    if (is_single) {
+      __ z_cebr(lreg, rreg);
+    } else {
+      __ z_cdbr(lreg, rreg);
+    }
+    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(dreg, 0);
+      __ z_locgr(dreg, one,       is_unordered_less ? Assembler::bcondHigh            : Assembler::bcondHighOrNotOrdered);
+      __ z_locgr(dreg, minus_one, is_unordered_less ? Assembler::bcondLowOrNotOrdered : Assembler::bcondLow);
+    } else {
+      __ clear_reg(dreg, true, false);
+      __ z_bre(done); // if (left == right) dst = 0
+
+      // if (left > right || ((code ~= cmpg) && (left <> right)) dst := 1
+      __ z_lhi(dreg, 1);
+      __ z_brc(is_unordered_less ? Assembler::bcondHigh : Assembler::bcondHighOrNotOrdered, done);
+
+      // if (left < right || ((code ~= cmpl) && (left <> right)) dst := -1
+      __ z_lhi(dreg, -1);
+    }
+  } else {
+    assert(code == lir_cmp_l2i, "check");
+    if (VM_Version::has_LoadStoreConditional()) {
+      Register one       = Z_R0_scratch;
+      Register minus_one = Z_R1_scratch;
+      __ z_cgr(left->as_register_lo(), right->as_register_lo());
+      __ z_lghi(minus_one, -1);
+      __ z_lghi(one,  1);
+      __ z_lghi(dreg, 0);
+      __ z_locgr(dreg, one, Assembler::bcondHigh);
+      __ z_locgr(dreg, minus_one, Assembler::bcondLow);
+    } else {
+      __ z_cgr(left->as_register_lo(), right->as_register_lo());
+      __ z_lghi(dreg,  0);     // eq value
+      __ z_bre(done);
+      __ z_lghi(dreg,  1);     // gt value
+      __ z_brh(done);
+      __ z_lghi(dreg, -1);     // lt value
+    }
+  }
+  __ bind(done);
+}
+
+// result = condition ? opr1 : opr2
+void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type) {
+  Assembler::branch_condition acond = Assembler::bcondEqual, ncond = Assembler::bcondNotEqual;
+  switch (condition) {
+    case lir_cond_equal:        acond = Assembler::bcondEqual;    ncond = Assembler::bcondNotEqual; break;
+    case lir_cond_notEqual:     acond = Assembler::bcondNotEqual; ncond = Assembler::bcondEqual;    break;
+    case lir_cond_less:         acond = Assembler::bcondLow;      ncond = Assembler::bcondNotLow;   break;
+    case lir_cond_lessEqual:    acond = Assembler::bcondNotHigh;  ncond = Assembler::bcondHigh;     break;
+    case lir_cond_greaterEqual: acond = Assembler::bcondNotLow;   ncond = Assembler::bcondLow;      break;
+    case lir_cond_greater:      acond = Assembler::bcondHigh;     ncond = Assembler::bcondNotHigh;  break;
+    case lir_cond_belowEqual:   acond = Assembler::bcondNotHigh;  ncond = Assembler::bcondHigh;     break;
+    case lir_cond_aboveEqual:   acond = Assembler::bcondNotLow;   ncond = Assembler::bcondLow;      break;
+    default:                    ShouldNotReachHere();
+  }
+
+  if (opr1->is_cpu_register()) {
+    reg2reg(opr1, result);
+  } else if (opr1->is_stack()) {
+    stack2reg(opr1, result, result->type());
+  } else if (opr1->is_constant()) {
+    const2reg(opr1, result, lir_patch_none, NULL);
+  } else {
+    ShouldNotReachHere();
+  }
+
+  if (VM_Version::has_LoadStoreConditional() && !opr2->is_constant()) {
+    // Optimized version that does not require a branch.
+    if (opr2->is_single_cpu()) {
+      assert(opr2->cpu_regnr() != result->cpu_regnr(), "opr2 already overwritten by previous move");
+      __ z_locgr(result->as_register(), opr2->as_register(), ncond);
+    } else if (opr2->is_double_cpu()) {
+      assert(opr2->cpu_regnrLo() != result->cpu_regnrLo() && opr2->cpu_regnrLo() != result->cpu_regnrHi(), "opr2 already overwritten by previous move");
+      assert(opr2->cpu_regnrHi() != result->cpu_regnrLo() && opr2->cpu_regnrHi() != result->cpu_regnrHi(), "opr2 already overwritten by previous move");
+      __ z_locgr(result->as_register_lo(), opr2->as_register_lo(), ncond);
+    } else if (opr2->is_single_stack()) {
+      __ z_loc(result->as_register(), frame_map()->address_for_slot(opr2->single_stack_ix()), ncond);
+    } else if (opr2->is_double_stack()) {
+      __ z_locg(result->as_register_lo(), frame_map()->address_for_slot(opr2->double_stack_ix()), ncond);
+    } else {
+      ShouldNotReachHere();
+    }
+  } else {
+    Label skip;
+    __ z_brc(acond, skip);
+    if (opr2->is_cpu_register()) {
+      reg2reg(opr2, result);
+    } else if (opr2->is_stack()) {
+      stack2reg(opr2, result, result->type());
+    } else if (opr2->is_constant()) {
+      const2reg(opr2, result, lir_patch_none, NULL);
+    } else {
+      ShouldNotReachHere();
+    }
+    __ bind(skip);
+  }
+}
+
+void LIR_Assembler::arith_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dest,
+                             CodeEmitInfo* info, bool pop_fpu_stack) {
+  assert(info == NULL, "should never be used, idiv/irem and ldiv/lrem not handled by this method");
+
+  if (left->is_single_cpu()) {
+    assert(left == dest, "left and dest must be equal");
+    Register lreg = left->as_register();
+
+    if (right->is_single_cpu()) {
+      // cpu register - cpu register
+      Register rreg = right->as_register();
+      switch (code) {
+        case lir_add: __ z_ar (lreg, rreg); break;
+        case lir_sub: __ z_sr (lreg, rreg); break;
+        case lir_mul: __ z_msr(lreg, rreg); break;
+        default: ShouldNotReachHere();
+      }
+
+    } else if (right->is_stack()) {
+      // cpu register - stack
+      Address raddr = frame_map()->address_for_slot(right->single_stack_ix());
+      switch (code) {
+        case lir_add: __ z_ay(lreg, raddr); break;
+        case lir_sub: __ z_sy(lreg, raddr); break;
+        default: ShouldNotReachHere();
+      }
+
+    } else if (right->is_constant()) {
+      // cpu register - constant
+      jint c = right->as_constant_ptr()->as_jint();
+      switch (code) {
+        case lir_add: __ z_agfi(lreg, c);  break;
+        case lir_sub: __ z_agfi(lreg, -c); break; // note: -min_jint == min_jint
+        case lir_mul: __ z_msfi(lreg, c);  break;
+        default: ShouldNotReachHere();
+      }
+
+    } else {
+      ShouldNotReachHere();
+    }
+
+  } else if (left->is_double_cpu()) {
+    assert(left == dest, "left and dest must be equal");
+    Register lreg_lo = left->as_register_lo();
+    Register lreg_hi = left->as_register_hi();
+
+    if (right->is_double_cpu()) {
+      // cpu register - cpu register
+      Register rreg_lo = right->as_register_lo();
+      Register rreg_hi = right->as_register_hi();
+      assert_different_registers(lreg_lo, rreg_lo);
+      switch (code) {
+        case lir_add:
+          __ z_agr(lreg_lo, rreg_lo);
+          break;
+        case lir_sub:
+          __ z_sgr(lreg_lo, rreg_lo);
+          break;
+        case lir_mul:
+          __ z_msgr(lreg_lo, rreg_lo);
+          break;
+        default:
+          ShouldNotReachHere();
+      }
+
+    } else if (right->is_constant()) {
+      // cpu register - constant
+      jlong c = right->as_constant_ptr()->as_jlong_bits();
+      switch (code) {
+        case lir_add: __ z_agfi(lreg_lo, c); break;
+        case lir_sub:
+          if (c != min_jint) {
+                      __ z_agfi(lreg_lo, -c);
+          } else {
+            // -min_jint cannot be represented as simm32 in z_agfi
+            // min_jint sign extended:      0xffffffff80000000
+            // -min_jint as 64 bit integer: 0x0000000080000000
+            // 0x80000000 can be represented as uimm32 in z_algfi
+            // lreg_lo := lreg_lo + -min_jint == lreg_lo + 0x80000000
+                      __ z_algfi(lreg_lo, UCONST64(0x80000000));
+          }
+          break;
+        case lir_mul: __ z_msgfi(lreg_lo, c); break;
+        default:
+          ShouldNotReachHere();
+      }
+
+    } else {
+      ShouldNotReachHere();
+    }
+
+  } else if (left->is_single_fpu()) {
+    assert(left == dest, "left and dest must be equal");
+    FloatRegister lreg = left->as_float_reg();
+    FloatRegister rreg = right->is_single_fpu() ? right->as_float_reg() : fnoreg;
+    Address raddr;
+
+    if (rreg == fnoreg) {
+      assert(right->is_single_stack(), "constants should be loaded into register");
+      raddr = frame_map()->address_for_slot(right->single_stack_ix());
+      if (!Immediate::is_uimm12(raddr.disp())) {
+        __ mem2freg_opt(rreg = Z_fscratch_1, raddr, false);
+      }
+    }
+
+    if (rreg != fnoreg) {
+      switch (code) {
+        case lir_add: __ z_aebr(lreg, rreg);  break;
+        case lir_sub: __ z_sebr(lreg, rreg);  break;
+        case lir_mul_strictfp: // fall through
+        case lir_mul: __ z_meebr(lreg, rreg); break;
+        case lir_div_strictfp: // fall through
+        case lir_div: __ z_debr(lreg, rreg);  break;
+        default: ShouldNotReachHere();
+      }
+    } else {
+      switch (code) {
+        case lir_add: __ z_aeb(lreg, raddr);  break;
+        case lir_sub: __ z_seb(lreg, raddr);  break;
+        case lir_mul_strictfp: // fall through
+        case lir_mul: __ z_meeb(lreg, raddr);  break;
+        case lir_div_strictfp: // fall through
+        case lir_div: __ z_deb(lreg, raddr);  break;
+        default: ShouldNotReachHere();
+      }
+    }
+  } else if (left->is_double_fpu()) {
+    assert(left == dest, "left and dest must be equal");
+    FloatRegister lreg = left->as_double_reg();
+    FloatRegister rreg = right->is_double_fpu() ? right->as_double_reg() : fnoreg;
+    Address raddr;
+
+    if (rreg == fnoreg) {
+      assert(right->is_double_stack(), "constants should be loaded into register");
+      raddr = frame_map()->address_for_slot(right->double_stack_ix());
+      if (!Immediate::is_uimm12(raddr.disp())) {
+        __ mem2freg_opt(rreg = Z_fscratch_1, raddr, true);
+      }
+    }
+
+    if (rreg != fnoreg) {
+      switch (code) {
+        case lir_add: __ z_adbr(lreg, rreg); break;
+        case lir_sub: __ z_sdbr(lreg, rreg); break;
+        case lir_mul_strictfp: // fall through
+        case lir_mul: __ z_mdbr(lreg, rreg); break;
+        case lir_div_strictfp: // fall through
+        case lir_div: __ z_ddbr(lreg, rreg); break;
+        default: ShouldNotReachHere();
+      }
+    } else {
+      switch (code) {
+        case lir_add: __ z_adb(lreg, raddr); break;
+        case lir_sub: __ z_sdb(lreg, raddr); break;
+        case lir_mul_strictfp: // fall through
+        case lir_mul: __ z_mdb(lreg, raddr); break;
+        case lir_div_strictfp: // fall through
+        case lir_div: __ z_ddb(lreg, raddr); break;
+        default: ShouldNotReachHere();
+      }
+    }
+  } else if (left->is_address()) {
+    assert(left == dest, "left and dest must be equal");
+    assert(code == lir_add, "unsupported operation");
+    assert(right->is_constant(), "unsupported operand");
+    jint c = right->as_constant_ptr()->as_jint();
+    LIR_Address* lir_addr = left->as_address_ptr();
+    Address addr = as_Address(lir_addr);
+    switch (lir_addr->type()) {
+      case T_INT:
+        __ add2mem_32(addr, c, Z_R1_scratch);
+        break;
+      case T_LONG:
+        __ add2mem_64(addr, c, Z_R1_scratch);
+        break;
+      default:
+        ShouldNotReachHere();
+    }
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::fpop() {
+  // do nothing
+}
+
+void LIR_Assembler::intrinsic_op(LIR_Code code, LIR_Opr value, LIR_Opr thread, LIR_Opr dest, LIR_Op* op) {
+  switch (code) {
+    case lir_sqrt: {
+      assert(!thread->is_valid(), "there is no need for a thread_reg for dsqrt");
+      FloatRegister src_reg = value->as_double_reg();
+      FloatRegister dst_reg = dest->as_double_reg();
+      __ z_sqdbr(dst_reg, src_reg);
+      break;
+    }
+    case lir_abs: {
+      assert(!thread->is_valid(), "there is no need for a thread_reg for fabs");
+      FloatRegister src_reg = value->as_double_reg();
+      FloatRegister dst_reg = dest->as_double_reg();
+      __ z_lpdbr(dst_reg, src_reg);
+      break;
+    }
+    default: {
+      ShouldNotReachHere();
+      break;
+    }
+  }
+}
+
+void LIR_Assembler::logic_op(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr dst) {
+  if (left->is_single_cpu()) {
+    Register reg = left->as_register();
+    if (right->is_constant()) {
+      int val = right->as_constant_ptr()->as_jint();
+      switch (code) {
+        case lir_logic_and: __ z_nilf(reg, val); break;
+        case lir_logic_or:  __ z_oilf(reg, val); break;
+        case lir_logic_xor: __ z_xilf(reg, val); break;
+        default: ShouldNotReachHere();
+      }
+    } else if (right->is_stack()) {
+      Address raddr = frame_map()->address_for_slot(right->single_stack_ix());
+      switch (code) {
+        case lir_logic_and: __ z_ny(reg, raddr); break;
+        case lir_logic_or:  __ z_oy(reg, raddr); break;
+        case lir_logic_xor: __ z_xy(reg, raddr); break;
+        default: ShouldNotReachHere();
+      }
+    } else {
+      Register rright = right->as_register();
+      switch (code) {
+        case lir_logic_and: __ z_nr(reg, rright); break;
+        case lir_logic_or : __ z_or(reg, rright); break;
+        case lir_logic_xor: __ z_xr(reg, rright); break;
+        default: ShouldNotReachHere();
+      }
+    }
+    move_regs(reg, dst->as_register());
+  } else {
+    Register l_lo = left->as_register_lo();
+    if (right->is_constant()) {
+      __ load_const_optimized(Z_R1_scratch, right->as_constant_ptr()->as_jlong());
+      switch (code) {
+        case lir_logic_and:
+          __ z_ngr(l_lo, Z_R1_scratch);
+          break;
+        case lir_logic_or:
+          __ z_ogr(l_lo, Z_R1_scratch);
+          break;
+        case lir_logic_xor:
+          __ z_xgr(l_lo, Z_R1_scratch);
+          break;
+        default: ShouldNotReachHere();
+      }
+    } else {
+      Register r_lo;
+      if (right->type() == T_OBJECT || right->type() == T_ARRAY) {
+        r_lo = right->as_register();
+      } else {
+        r_lo = right->as_register_lo();
+      }
+      switch (code) {
+        case lir_logic_and:
+          __ z_ngr(l_lo, r_lo);
+          break;
+        case lir_logic_or:
+          __ z_ogr(l_lo, r_lo);
+          break;
+        case lir_logic_xor:
+          __ z_xgr(l_lo, r_lo);
+          break;
+        default: ShouldNotReachHere();
+      }
+    }
+
+    Register dst_lo = dst->as_register_lo();
+
+    move_regs(l_lo, dst_lo);
+  }
+}
+
+// See operand selection in LIRGenerator::do_ArithmeticOp_Int().
+void LIR_Assembler::arithmetic_idiv(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Opr temp, LIR_Opr result, CodeEmitInfo* info) {
+  if (left->is_double_cpu()) {
+    // 64 bit integer case
+    assert(left->is_double_cpu(), "left must be register");
+    assert(right->is_double_cpu() || is_power_of_2_long(right->as_jlong()),
+           "right must be register or power of 2 constant");
+    assert(result->is_double_cpu(), "result must be register");
+
+    Register lreg = left->as_register_lo();
+    Register dreg = result->as_register_lo();
+
+    if (right->is_constant()) {
+      // Convert division by a power of two into some shifts and logical operations.
+      Register treg1 = Z_R0_scratch;
+      Register treg2 = Z_R1_scratch;
+      jlong divisor = right->as_jlong();
+      jlong log_divisor = log2_long(right->as_jlong());
+
+      if (divisor == min_jlong) {
+        // Min_jlong is special. Result is '0' except for min_jlong/min_jlong = 1.
+        if (dreg == lreg) {
+          NearLabel done;
+          __ load_const_optimized(treg2, min_jlong);
+          __ z_cgr(lreg, treg2);
+          __ z_lghi(dreg, 0);           // Preserves condition code.
+          __ z_brne(done);
+          __ z_lghi(dreg, 1);           // min_jlong / min_jlong = 1
+          __ bind(done);
+        } else {
+          assert_different_registers(dreg, lreg);
+          NearLabel done;
+          __ z_lghi(dreg, 0);
+          __ compare64_and_branch(lreg, min_jlong, Assembler::bcondNotEqual, done);
+          __ z_lghi(dreg, 1);
+          __ bind(done);
+        }
+        return;
+      }
+      __ move_reg_if_needed(dreg, T_LONG, lreg, T_LONG);
+      if (divisor == 2) {
+        __ z_srlg(treg2, dreg, 63);     // dividend < 0 ? 1 : 0
+      } else {
+        __ z_srag(treg2, dreg, 63);     // dividend < 0 ? -1 : 0
+        __ and_imm(treg2, divisor - 1, treg1, true);
+      }
+      if (code == lir_idiv) {
+        __ z_agr(dreg, treg2);
+        __ z_srag(dreg, dreg, log_divisor);
+      } else {
+        assert(code == lir_irem, "check");
+        __ z_agr(treg2, dreg);
+        __ and_imm(treg2, ~(divisor - 1), treg1, true);
+        __ z_sgr(dreg, treg2);
+      }
+      return;
+    }
+
+    // Divisor is not a power of 2 constant.
+    Register rreg = right->as_register_lo();
+    Register treg = temp->as_register_lo();
+    assert(right->is_double_cpu(), "right must be register");
+    assert(lreg == Z_R11, "see ldivInOpr()");
+    assert(rreg != lreg, "right register must not be same as left register");
+    assert((code == lir_idiv && dreg == Z_R11 && treg == Z_R10) ||
+           (code == lir_irem && dreg == Z_R10 && treg == Z_R11), "see ldivInOpr(), ldivOutOpr(), lremOutOpr()");
+
+    Register R1 = lreg->predecessor();
+    Register R2 = rreg;
+    assert(code != lir_idiv || lreg==dreg, "see code below");
+    if (code == lir_idiv) {
+      __ z_lcgr(lreg, lreg);
+    } else {
+      __ clear_reg(dreg, true, false);
+    }
+    NearLabel done;
+    __ compare64_and_branch(R2, -1, Assembler::bcondEqual, done);
+    if (code == lir_idiv) {
+      __ z_lcgr(lreg, lreg); // Revert lcgr above.
+    }
+    if (ImplicitDiv0Checks) {
+      // No debug info because the idiv won't trap.
+      // Add_debug_info_for_div0 would instantiate another DivByZeroStub,
+      // which is unnecessary, too.
+      add_debug_info_for_div0(__ offset(), info);
+    }
+    __ z_dsgr(R1, R2);
+    __ bind(done);
+    return;
+  }
+
+  // 32 bit integer case
+
+  assert(left->is_single_cpu(), "left must be register");
+  assert(right->is_single_cpu() || is_power_of_2(right->as_jint()), "right must be register or power of 2 constant");
+  assert(result->is_single_cpu(), "result must be register");
+
+  Register lreg = left->as_register();
+  Register dreg = result->as_register();
+
+  if (right->is_constant()) {
+    // Convert division by a power of two into some shifts and logical operations.
+    Register treg1 = Z_R0_scratch;
+    Register treg2 = Z_R1_scratch;
+    jlong divisor = right->as_jint();
+    jlong log_divisor = log2_long(right->as_jint());
+    __ move_reg_if_needed(dreg, T_LONG, lreg, T_INT); // sign extend
+    if (divisor == 2) {
+      __ z_srlg(treg2, dreg, 63);     // dividend < 0 ?  1 : 0
+    } else {
+      __ z_srag(treg2, dreg, 63);     // dividend < 0 ? -1 : 0
+      __ and_imm(treg2, divisor - 1, treg1, true);
+    }
+    if (code == lir_idiv) {
+      __ z_agr(dreg, treg2);
+      __ z_srag(dreg, dreg, log_divisor);
+    } else {
+      assert(code == lir_irem, "check");
+      __ z_agr(treg2, dreg);
+      __ and_imm(treg2, ~(divisor - 1), treg1, true);
+      __ z_sgr(dreg, treg2);
+    }
+    return;
+  }
+
+  // Divisor is not a power of 2 constant.
+  Register rreg = right->as_register();
+  Register treg = temp->as_register();
+  assert(right->is_single_cpu(), "right must be register");
+  assert(lreg == Z_R11, "left register must be rax,");
+  assert(rreg != lreg, "right register must not be same as left register");
+  assert((code == lir_idiv && dreg == Z_R11 && treg == Z_R10)
+      || (code == lir_irem && dreg == Z_R10 && treg == Z_R11), "see divInOpr(), divOutOpr(), remOutOpr()");
+
+  Register R1 = lreg->predecessor();
+  Register R2 = rreg;
+  __ move_reg_if_needed(lreg, T_LONG, lreg, T_INT); // sign extend
+  if (ImplicitDiv0Checks) {
+    // No debug info because the idiv won't trap.
+    // Add_debug_info_for_div0 would instantiate another DivByZeroStub,
+    // which is unnecessary, too.
+    add_debug_info_for_div0(__ offset(), info);
+  }
+  __ z_dsgfr(R1, R2);
+}
+
+void LIR_Assembler::throw_op(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) {
+  assert(exceptionOop->as_register() == Z_EXC_OOP, "should match");
+  assert(exceptionPC->as_register() == Z_EXC_PC, "should match");
+
+  // Exception object is not added to oop map by LinearScan
+  // (LinearScan assumes that no oops are in fixed registers).
+  info->add_register_oop(exceptionOop);
+
+  // Reuse the debug info from the safepoint poll for the throw op itself.
+  __ get_PC(Z_EXC_PC);
+  add_call_info(__ offset(), info); // for exception handler
+  address stub = Runtime1::entry_for (compilation()->has_fpu_code() ? Runtime1::handle_exception_id
+                                                                    : Runtime1::handle_exception_nofpu_id);
+  emit_call_c(stub);
+}
+
+void LIR_Assembler::unwind_op(LIR_Opr exceptionOop) {
+  assert(exceptionOop->as_register() == Z_EXC_OOP, "should match");
+
+  __ branch_optimized(Assembler::bcondAlways, _unwind_handler_entry);
+}
+
+void LIR_Assembler::emit_arraycopy(LIR_OpArrayCopy* op) {
+  ciArrayKlass* default_type = op->expected_type();
+  Register src = op->src()->as_register();
+  Register dst = op->dst()->as_register();
+  Register src_pos = op->src_pos()->as_register();
+  Register dst_pos = op->dst_pos()->as_register();
+  Register length  = op->length()->as_register();
+  Register tmp = op->tmp()->as_register();
+
+  CodeStub* stub = op->stub();
+  int flags = op->flags();
+  BasicType basic_type = default_type != NULL ? default_type->element_type()->basic_type() : T_ILLEGAL;
+  if (basic_type == T_ARRAY) basic_type = T_OBJECT;
+
+  // If we don't know anything, just go through the generic arraycopy.
+  if (default_type == NULL) {
+    Label done;
+    // Save outgoing arguments in callee saved registers (C convention) in case
+    // a call to System.arraycopy is needed.
+    Register callee_saved_src     = Z_R10;
+    Register callee_saved_src_pos = Z_R11;
+    Register callee_saved_dst     = Z_R12;
+    Register callee_saved_dst_pos = Z_R13;
+    Register callee_saved_length  = Z_ARG5; // Z_ARG5 == Z_R6 is callee saved.
+
+    __ lgr_if_needed(callee_saved_src, src);
+    __ lgr_if_needed(callee_saved_src_pos, src_pos);
+    __ lgr_if_needed(callee_saved_dst, dst);
+    __ lgr_if_needed(callee_saved_dst_pos, dst_pos);
+    __ lgr_if_needed(callee_saved_length, length);
+
+    // C function requires 64 bit values.
+    __ z_lgfr(src_pos, src_pos);
+    __ z_lgfr(dst_pos, dst_pos);
+    __ z_lgfr(length, length);
+
+    address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy);
+
+    address copyfunc_addr = StubRoutines::generic_arraycopy();
+
+    // Pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint.
+
+    // The arguments are in the corresponding registers.
+    assert(Z_ARG1 == src,     "assumption");
+    assert(Z_ARG2 == src_pos, "assumption");
+    assert(Z_ARG3 == dst,     "assumption");
+    assert(Z_ARG4 == dst_pos, "assumption");
+    assert(Z_ARG5 == length,  "assumption");
+    if (copyfunc_addr == NULL) { // Use C version if stub was not generated.
+      emit_call_c(C_entry);
+    } else {
+#ifndef PRODUCT
+      if (PrintC1Statistics) {
+        __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_generic_arraycopystub_cnt);
+        __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
+      }
+#endif
+      emit_call_c(copyfunc_addr);
+    }
+    CHECK_BAILOUT();
+
+    __ compare32_and_branch(Z_RET, (intptr_t)0, Assembler::bcondEqual, *stub->continuation());
+
+    if (copyfunc_addr != NULL) {
+      __ z_lgr(tmp, Z_RET);
+      __ z_xilf(tmp, -1);
+    }
+
+    // Restore values from callee saved registers so they are where the stub
+    // expects them.
+    __ lgr_if_needed(src, callee_saved_src);
+    __ lgr_if_needed(src_pos, callee_saved_src_pos);
+    __ lgr_if_needed(dst, callee_saved_dst);
+    __ lgr_if_needed(dst_pos, callee_saved_dst_pos);
+    __ lgr_if_needed(length, callee_saved_length);
+
+    if (copyfunc_addr != NULL) {
+      __ z_sr(length, tmp);
+      __ z_ar(src_pos, tmp);
+      __ z_ar(dst_pos, tmp);
+    }
+    __ branch_optimized(Assembler::bcondAlways, *stub->entry());
+
+    __ bind(*stub->continuation());
+    return;
+  }
+
+  assert(default_type != NULL && default_type->is_array_klass() && default_type->is_loaded(), "must be true at this point");
+
+  int elem_size = type2aelembytes(basic_type);
+  int shift_amount;
+
+  switch (elem_size) {
+    case 1 :
+      shift_amount = 0;
+      break;
+    case 2 :
+      shift_amount = 1;
+      break;
+    case 4 :
+      shift_amount = 2;
+      break;
+    case 8 :
+      shift_amount = 3;
+      break;
+    default:
+      shift_amount = -1;
+      ShouldNotReachHere();
+  }
+
+  Address src_length_addr = Address(src, arrayOopDesc::length_offset_in_bytes());
+  Address dst_length_addr = Address(dst, arrayOopDesc::length_offset_in_bytes());
+  Address src_klass_addr = Address(src, oopDesc::klass_offset_in_bytes());
+  Address dst_klass_addr = Address(dst, oopDesc::klass_offset_in_bytes());
+
+  // Length and pos's are all sign extended at this point on 64bit.
+
+  // test for NULL
+  if (flags & LIR_OpArrayCopy::src_null_check) {
+    __ compareU64_and_branch(src, (intptr_t)0, Assembler::bcondZero, *stub->entry());
+  }
+  if (flags & LIR_OpArrayCopy::dst_null_check) {
+    __ compareU64_and_branch(dst, (intptr_t)0, Assembler::bcondZero, *stub->entry());
+  }
+
+  // Check if negative.
+  if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
+    __ compare32_and_branch(src_pos, (intptr_t)0, Assembler::bcondLow, *stub->entry());
+  }
+  if (flags & LIR_OpArrayCopy::dst_pos_positive_check) {
+    __ compare32_and_branch(dst_pos, (intptr_t)0, Assembler::bcondLow, *stub->entry());
+  }
+
+  // If the compiler was not able to prove that exact type of the source or the destination
+  // of the arraycopy is an array type, check at runtime if the source or the destination is
+  // an instance type.
+  if (flags & LIR_OpArrayCopy::type_check) {
+    assert(Klass::_lh_neutral_value == 0, "or replace z_lt instructions");
+
+    if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+      __ load_klass(tmp, dst);
+      __ z_lt(tmp, Address(tmp, in_bytes(Klass::layout_helper_offset())));
+      __ branch_optimized(Assembler::bcondNotLow, *stub->entry());
+    }
+
+    if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+      __ load_klass(tmp, src);
+      __ z_lt(tmp, Address(tmp, in_bytes(Klass::layout_helper_offset())));
+      __ branch_optimized(Assembler::bcondNotLow, *stub->entry());
+    }
+  }
+
+  if (flags & LIR_OpArrayCopy::src_range_check) {
+    __ z_la(tmp, Address(src_pos, length));
+    __ z_cl(tmp, src_length_addr);
+    __ branch_optimized(Assembler::bcondHigh, *stub->entry());
+  }
+  if (flags & LIR_OpArrayCopy::dst_range_check) {
+    __ z_la(tmp, Address(dst_pos, length));
+    __ z_cl(tmp, dst_length_addr);
+    __ branch_optimized(Assembler::bcondHigh, *stub->entry());
+  }
+
+  if (flags & LIR_OpArrayCopy::length_positive_check) {
+    __ z_ltr(length, length);
+    __ branch_optimized(Assembler::bcondNegative, *stub->entry());
+  }
+
+  // Stubs require 64 bit values.
+  __ z_lgfr(src_pos, src_pos); // int -> long
+  __ z_lgfr(dst_pos, dst_pos); // int -> long
+  __ z_lgfr(length, length);   // int -> long
+
+  if (flags & LIR_OpArrayCopy::type_check) {
+    // We don't know the array types are compatible.
+    if (basic_type != T_OBJECT) {
+      // Simple test for basic type arrays.
+      if (UseCompressedClassPointers) {
+        __ z_l(tmp, src_klass_addr);
+        __ z_c(tmp, dst_klass_addr);
+      } else {
+        __ z_lg(tmp, src_klass_addr);
+        __ z_cg(tmp, dst_klass_addr);
+      }
+      __ branch_optimized(Assembler::bcondNotEqual, *stub->entry());
+    } else {
+      // For object arrays, if src is a sub class of dst then we can
+      // safely do the copy.
+      NearLabel cont, slow;
+      Register src_klass = Z_R1_scratch;
+      Register dst_klass = Z_R10;
+
+      __ load_klass(src_klass, src);
+      __ load_klass(dst_klass, dst);
+
+      __ check_klass_subtype_fast_path(src_klass, dst_klass, tmp, &cont, &slow, NULL);
+
+      store_parameter(src_klass, 0); // sub
+      store_parameter(dst_klass, 1); // super
+      emit_call_c(Runtime1::entry_for (Runtime1::slow_subtype_check_id));
+      CHECK_BAILOUT();
+      // Sets condition code 0 for match (2 otherwise).
+      __ branch_optimized(Assembler::bcondEqual, cont);
+
+      __ bind(slow);
+
+      address copyfunc_addr = StubRoutines::checkcast_arraycopy();
+      if (copyfunc_addr != NULL) { // use stub if available
+        // Src is not a sub class of dst so we have to do a
+        // per-element check.
+
+        int mask = LIR_OpArrayCopy::src_objarray|LIR_OpArrayCopy::dst_objarray;
+        if ((flags & mask) != mask) {
+          // Check that at least both of them object arrays.
+          assert(flags & mask, "one of the two should be known to be an object array");
+
+          if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+            __ load_klass(tmp, src);
+          } else if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+            __ load_klass(tmp, dst);
+          }
+          Address klass_lh_addr(tmp, Klass::layout_helper_offset());
+          jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
+          __ load_const_optimized(Z_R1_scratch, objArray_lh);
+          __ z_c(Z_R1_scratch, klass_lh_addr);
+          __ branch_optimized(Assembler::bcondNotEqual, *stub->entry());
+        }
+
+        // Save outgoing arguments in callee saved registers (C convention) in case
+        // a call to System.arraycopy is needed.
+        Register callee_saved_src     = Z_R10;
+        Register callee_saved_src_pos = Z_R11;
+        Register callee_saved_dst     = Z_R12;
+        Register callee_saved_dst_pos = Z_R13;
+        Register callee_saved_length  = Z_ARG5; // Z_ARG5 == Z_R6 is callee saved.
+
+        __ lgr_if_needed(callee_saved_src, src);
+        __ lgr_if_needed(callee_saved_src_pos, src_pos);
+        __ lgr_if_needed(callee_saved_dst, dst);
+        __ lgr_if_needed(callee_saved_dst_pos, dst_pos);
+        __ lgr_if_needed(callee_saved_length, length);
+
+        __ z_llgfr(length, length); // Higher 32bits must be null.
+
+        __ z_sllg(Z_ARG1, src_pos, shift_amount); // index -> byte offset
+        __ z_sllg(Z_ARG2, dst_pos, shift_amount); // index -> byte offset
+
+        __ z_la(Z_ARG1, Address(src, Z_ARG1, arrayOopDesc::base_offset_in_bytes(basic_type)));
+        assert_different_registers(Z_ARG1, dst, dst_pos, length);
+        __ z_la(Z_ARG2, Address(dst, Z_ARG2, arrayOopDesc::base_offset_in_bytes(basic_type)));
+        assert_different_registers(Z_ARG2, dst, length);
+
+        __ z_lgr(Z_ARG3, length);
+        assert_different_registers(Z_ARG3, dst);
+
+        __ load_klass(Z_ARG5, dst);
+        __ z_lg(Z_ARG5, Address(Z_ARG5, ObjArrayKlass::element_klass_offset()));
+        __ z_lg(Z_ARG4, Address(Z_ARG5, Klass::super_check_offset_offset()));
+        emit_call_c(copyfunc_addr);
+        CHECK_BAILOUT();
+
+#ifndef PRODUCT
+        if (PrintC1Statistics) {
+          NearLabel failed;
+          __ compareU32_and_branch(Z_RET, (intptr_t)0, Assembler::bcondNotEqual, failed);
+          __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_arraycopy_checkcast_cnt);
+          __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
+          __ bind(failed);
+        }
+#endif
+
+        __ compareU32_and_branch(Z_RET, (intptr_t)0, Assembler::bcondEqual, *stub->continuation());
+
+#ifndef PRODUCT
+        if (PrintC1Statistics) {
+          __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_arraycopy_checkcast_attempt_cnt);
+          __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
+        }
+#endif
+
+        __ z_lgr(tmp, Z_RET);
+        __ z_xilf(tmp, -1);
+
+        // Restore previously spilled arguments
+        __ lgr_if_needed(src, callee_saved_src);
+        __ lgr_if_needed(src_pos, callee_saved_src_pos);
+        __ lgr_if_needed(dst, callee_saved_dst);
+        __ lgr_if_needed(dst_pos, callee_saved_dst_pos);
+        __ lgr_if_needed(length, callee_saved_length);
+
+        __ z_sr(length, tmp);
+        __ z_ar(src_pos, tmp);
+        __ z_ar(dst_pos, tmp);
+      }
+
+      __ branch_optimized(Assembler::bcondAlways, *stub->entry());
+
+      __ bind(cont);
+    }
+  }
+
+#ifdef ASSERT
+  if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) {
+    // Sanity check the known type with the incoming class. For the
+    // primitive case the types must match exactly with src.klass and
+    // dst.klass each exactly matching the default type. For the
+    // object array case, if no type check is needed then either the
+    // dst type is exactly the expected type and the src type is a
+    // subtype which we can't check or src is the same array as dst
+    // but not necessarily exactly of type default_type.
+    NearLabel known_ok, halt;
+    metadata2reg(default_type->constant_encoding(), tmp);
+    if (UseCompressedClassPointers) {
+      __ encode_klass_not_null(tmp);
+    }
+
+    if (basic_type != T_OBJECT) {
+      if (UseCompressedClassPointers)         { __ z_c (tmp, dst_klass_addr); }
+      else                                    { __ z_cg(tmp, dst_klass_addr); }
+      __ branch_optimized(Assembler::bcondNotEqual, halt);
+      if (UseCompressedClassPointers)         { __ z_c (tmp, src_klass_addr); }
+      else                                    { __ z_cg(tmp, src_klass_addr); }
+      __ branch_optimized(Assembler::bcondEqual, known_ok);
+    } else {
+      if (UseCompressedClassPointers)         { __ z_c (tmp, dst_klass_addr); }
+      else                                    { __ z_cg(tmp, dst_klass_addr); }
+      __ branch_optimized(Assembler::bcondEqual, known_ok);
+      __ compareU64_and_branch(src, dst, Assembler::bcondEqual, known_ok);
+    }
+    __ bind(halt);
+    __ stop("incorrect type information in arraycopy");
+    __ bind(known_ok);
+  }
+#endif
+
+#ifndef PRODUCT
+  if (PrintC1Statistics) {
+    __ load_const_optimized(Z_R1_scratch, Runtime1::arraycopy_count_address(basic_type));
+    __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch);
+  }
+#endif
+
+  __ z_sllg(tmp, src_pos, shift_amount); // index -> byte offset
+  __ z_sllg(Z_R1_scratch, dst_pos, shift_amount); // index -> byte offset
+
+  assert_different_registers(Z_ARG1, dst, dst_pos, length);
+  __ z_la(Z_ARG1, Address(src, tmp, arrayOopDesc::base_offset_in_bytes(basic_type)));
+  assert_different_registers(Z_ARG2, length);
+  __ z_la(Z_ARG2, Address(dst, Z_R1_scratch, arrayOopDesc::base_offset_in_bytes(basic_type)));
+  __ lgr_if_needed(Z_ARG3, length);
+
+  bool disjoint = (flags & LIR_OpArrayCopy::overlapping) == 0;
+  bool aligned = (flags & LIR_OpArrayCopy::unaligned) == 0;
+  const char *name;
+  address entry = StubRoutines::select_arraycopy_function(basic_type, aligned, disjoint, name, false);
+  __ call_VM_leaf(entry);
+
+  __ bind(*stub->continuation());
+}
+
+void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, LIR_Opr count, LIR_Opr dest, LIR_Opr tmp) {
+  if (dest->is_single_cpu()) {
+    if (left->type() == T_OBJECT) {
+      switch (code) {
+        case lir_shl:  __ z_sllg (dest->as_register(), left->as_register(), 0, count->as_register()); break;
+        case lir_shr:  __ z_srag (dest->as_register(), left->as_register(), 0, count->as_register()); break;
+        case lir_ushr: __ z_srlg (dest->as_register(), left->as_register(), 0, count->as_register()); break;
+        default: ShouldNotReachHere();
+      }
+    } else {
+      assert(code == lir_shl || left == dest, "left and dest must be equal for 2 operand form right shifts");
+      Register masked_count = Z_R1_scratch;
+      __ z_lr(masked_count, count->as_register());
+      __ z_nill(masked_count, 31);
+      switch (code) {
+        case lir_shl:  __ z_sllg (dest->as_register(), left->as_register(), 0, masked_count); break;
+        case lir_shr:  __ z_sra  (dest->as_register(), 0, masked_count); break;
+        case lir_ushr: __ z_srl  (dest->as_register(), 0, masked_count); break;
+        default: ShouldNotReachHere();
+      }
+    }
+  } else {
+    switch (code) {
+      case lir_shl:  __ z_sllg (dest->as_register_lo(), left->as_register_lo(), 0, count->as_register()); break;
+      case lir_shr:  __ z_srag (dest->as_register_lo(), left->as_register_lo(), 0, count->as_register()); break;
+      case lir_ushr: __ z_srlg (dest->as_register_lo(), left->as_register_lo(), 0, count->as_register()); break;
+      default: ShouldNotReachHere();
+    }
+  }
+}
+
+void LIR_Assembler::shift_op(LIR_Code code, LIR_Opr left, jint count, LIR_Opr dest) {
+  if (left->type() == T_OBJECT) {
+    count = count & 63;  // Shouldn't shift by more than sizeof(intptr_t).
+    Register l = left->as_register();
+    Register d = dest->as_register_lo();
+    switch (code) {
+      case lir_shl:  __ z_sllg (d, l, count); break;
+      case lir_shr:  __ z_srag (d, l, count); break;
+      case lir_ushr: __ z_srlg (d, l, count); break;
+      default: ShouldNotReachHere();
+    }
+    return;
+  }
+  if (dest->is_single_cpu()) {
+    assert(code == lir_shl || left == dest, "left and dest must be equal for 2 operand form right shifts");
+    count = count & 0x1F; // Java spec
+    switch (code) {
+      case lir_shl:  __ z_sllg (dest->as_register(), left->as_register(), count); break;
+      case lir_shr:  __ z_sra  (dest->as_register(), count); break;
+      case lir_ushr: __ z_srl  (dest->as_register(), count); break;
+      default: ShouldNotReachHere();
+    }
+  } else if (dest->is_double_cpu()) {
+    count = count & 63; // Java spec
+    Register l = left->as_pointer_register();
+    Register d = dest->as_pointer_register();
+    switch (code) {
+      case lir_shl:  __ z_sllg (d, l, count); break;
+      case lir_shr:  __ z_srag (d, l, count); break;
+      case lir_ushr: __ z_srlg (d, l, count); break;
+      default: ShouldNotReachHere();
+    }
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::emit_alloc_obj(LIR_OpAllocObj* op) {
+  if (op->init_check()) {
+    // Make sure klass is initialized & doesn't have finalizer.
+    const int state_offset = in_bytes(InstanceKlass::init_state_offset());
+    Register iklass = op->klass()->as_register();
+    add_debug_info_for_null_check_here(op->stub()->info());
+    if (Immediate::is_uimm12(state_offset)) {
+      __ z_cli(state_offset, iklass, InstanceKlass::fully_initialized);
+    } else {
+      __ z_cliy(state_offset, iklass, InstanceKlass::fully_initialized);
+    }
+    __ branch_optimized(Assembler::bcondNotEqual, *op->stub()->entry()); // Use long branch, because slow_case might be far.
+  }
+  __ allocate_object(op->obj()->as_register(),
+                     op->tmp1()->as_register(),
+                     op->tmp2()->as_register(),
+                     op->header_size(),
+                     op->object_size(),
+                     op->klass()->as_register(),
+                     *op->stub()->entry());
+  __ bind(*op->stub()->continuation());
+  __ verify_oop(op->obj()->as_register());
+}
+
+void LIR_Assembler::emit_alloc_array(LIR_OpAllocArray* op) {
+  Register len = op->len()->as_register();
+  __ move_reg_if_needed(len, T_LONG, len, T_INT); // sign extend
+
+  if (UseSlowPath ||
+      (!UseFastNewObjectArray && (op->type() == T_OBJECT || op->type() == T_ARRAY)) ||
+      (!UseFastNewTypeArray   && (op->type() != T_OBJECT && op->type() != T_ARRAY))) {
+    __ z_brul(*op->stub()->entry());
+  } else {
+    __ allocate_array(op->obj()->as_register(),
+                      op->len()->as_register(),
+                      op->tmp1()->as_register(),
+                      op->tmp2()->as_register(),
+                      arrayOopDesc::header_size(op->type()),
+                      type2aelembytes(op->type()),
+                      op->klass()->as_register(),
+                      *op->stub()->entry());
+  }
+  __ bind(*op->stub()->continuation());
+}
+
+void LIR_Assembler::type_profile_helper(Register mdo, ciMethodData *md, ciProfileData *data,
+                                        Register recv, Register tmp1, Label* update_done) {
+  uint i;
+  for (i = 0; i < VirtualCallData::row_limit(); i++) {
+    Label next_test;
+    // See if the receiver is receiver[n].
+    Address receiver_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)));
+    __ z_cg(recv, receiver_addr);
+    __ z_brne(next_test);
+    Address data_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)));
+    __ add2mem_64(data_addr, DataLayout::counter_increment, tmp1);
+    __ branch_optimized(Assembler::bcondAlways, *update_done);
+    __ bind(next_test);
+  }
+
+  // Didn't find receiver; find next empty slot and fill it in.
+  for (i = 0; i < VirtualCallData::row_limit(); i++) {
+    Label next_test;
+    Address recv_addr(mdo, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_offset(i)));
+    __ z_ltg(Z_R0_scratch, recv_addr);
+    __ z_brne(next_test);
+    __ z_stg(recv, recv_addr);
+    __ load_const_optimized(tmp1, DataLayout::counter_increment);
+    __ z_stg(tmp1, md->byte_offset_of_slot(data, ReceiverTypeData::receiver_count_offset(i)), mdo);
+    __ branch_optimized(Assembler::bcondAlways, *update_done);
+    __ bind(next_test);
+  }
+}
+
+void LIR_Assembler::setup_md_access(ciMethod* method, int bci,
+                                    ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias) {
+  Unimplemented();
+}
+
+void LIR_Assembler::store_parameter(Register r, int param_num) {
+  assert(param_num >= 0, "invalid num");
+  int offset_in_bytes = param_num * BytesPerWord + FrameMap::first_available_sp_in_frame;
+  assert(offset_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
+  __ z_stg(r, offset_in_bytes, Z_SP);
+}
+
+void LIR_Assembler::store_parameter(jint c, int param_num) {
+  assert(param_num >= 0, "invalid num");
+  int offset_in_bytes = param_num * BytesPerWord + FrameMap::first_available_sp_in_frame;
+  assert(offset_in_bytes < frame_map()->reserved_argument_area_size(), "invalid offset");
+  __ store_const(Address(Z_SP, offset_in_bytes), c, Z_R1_scratch, true);
+}
+
+void LIR_Assembler::emit_typecheck_helper(LIR_OpTypeCheck *op, Label* success, Label* failure, Label* obj_is_null) {
+  // We always need a stub for the failure case.
+  CodeStub* stub = op->stub();
+  Register obj = op->object()->as_register();
+  Register k_RInfo = op->tmp1()->as_register();
+  Register klass_RInfo = op->tmp2()->as_register();
+  Register dst = op->result_opr()->as_register();
+  Register Rtmp1 = Z_R1_scratch;
+  ciKlass* k = op->klass();
+
+  assert(!op->tmp3()->is_valid(), "tmp3's not needed");
+
+  // Check if it needs to be profiled.
+  ciMethodData* md = NULL;
+  ciProfileData* data = NULL;
+
+  if (op->should_profile()) {
+    ciMethod* method = op->profiled_method();
+    assert(method != NULL, "Should have method");
+    int bci = op->profiled_bci();
+    md = method->method_data_or_null();
+    assert(md != NULL, "Sanity");
+    data = md->bci_to_data(bci);
+    assert(data != NULL,                "need data for type check");
+    assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
+  }
+
+  // Temp operands do not overlap with inputs, if this is their last
+  // use (end of range is exclusive), so a register conflict is possible.
+  if (obj == k_RInfo) {
+    k_RInfo = dst;
+  } else if (obj == klass_RInfo) {
+    klass_RInfo = dst;
+  }
+  assert_different_registers(obj, k_RInfo, klass_RInfo);
+
+  if (op->should_profile()) {
+    NearLabel not_null;
+    __ compareU64_and_branch(obj, (intptr_t) 0, Assembler::bcondNotEqual, not_null);
+    // Object is null; update MDO and exit.
+    Register mdo = klass_RInfo;
+    metadata2reg(md->constant_encoding(), mdo);
+    Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
+    int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
+    __ or2mem_8(data_addr, header_bits);
+    __ branch_optimized(Assembler::bcondAlways, *obj_is_null);
+    __ bind(not_null);
+  } else {
+    __ compareU64_and_branch(obj, (intptr_t) 0, Assembler::bcondEqual, *obj_is_null);
+  }
+
+  NearLabel profile_cast_failure, profile_cast_success;
+  Label *failure_target = op->should_profile() ? &profile_cast_failure : failure;
+  Label *success_target = op->should_profile() ? &profile_cast_success : success;
+
+  // Patching may screw with our temporaries on sparc,
+  // so let's do it before loading the class.
+  if (k->is_loaded()) {
+    metadata2reg(k->constant_encoding(), k_RInfo);
+  } else {
+    klass2reg_with_patching(k_RInfo, op->info_for_patch());
+  }
+  assert(obj != k_RInfo, "must be different");
+
+  __ verify_oop(obj);
+
+  // Get object class.
+  // Not a safepoint as obj null check happens earlier.
+  if (op->fast_check()) {
+    if (UseCompressedClassPointers) {
+      __ load_klass(klass_RInfo, obj);
+      __ compareU64_and_branch(k_RInfo, klass_RInfo, Assembler::bcondNotEqual, *failure_target);
+    } else {
+      __ z_cg(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes()));
+      __ branch_optimized(Assembler::bcondNotEqual, *failure_target);
+    }
+    // Successful cast, fall through to profile or jump.
+  } else {
+    bool need_slow_path = !k->is_loaded() ||
+                          ((int) k->super_check_offset() == in_bytes(Klass::secondary_super_cache_offset()));
+    intptr_t super_check_offset = k->is_loaded() ? k->super_check_offset() : -1L;
+    __ load_klass(klass_RInfo, obj);
+    // Perform the fast part of the checking logic.
+    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1,
+                                     (need_slow_path ? success_target : NULL),
+                                     failure_target, NULL,
+                                     RegisterOrConstant(super_check_offset));
+    if (need_slow_path) {
+      // Call out-of-line instance of __ check_klass_subtype_slow_path(...):
+      address a = Runtime1::entry_for (Runtime1::slow_subtype_check_id);
+      store_parameter(klass_RInfo, 0); // sub
+      store_parameter(k_RInfo, 1);     // super
+      emit_call_c(a); // Sets condition code 0 for match (2 otherwise).
+      CHECK_BAILOUT();
+      __ branch_optimized(Assembler::bcondNotEqual, *failure_target);
+      // Fall through to success case.
+    }
+  }
+
+  if (op->should_profile()) {
+    Register mdo = klass_RInfo, recv = k_RInfo;
+    assert_different_registers(obj, mdo, recv);
+    __ bind(profile_cast_success);
+    metadata2reg(md->constant_encoding(), mdo);
+    __ load_klass(recv, obj);
+    type_profile_helper(mdo, md, data, recv, Rtmp1, success);
+    __ branch_optimized(Assembler::bcondAlways, *success);
+
+    __ bind(profile_cast_failure);
+    metadata2reg(md->constant_encoding(), mdo);
+    __ add2mem_64(Address(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())), -(int)DataLayout::counter_increment, Rtmp1);
+    __ branch_optimized(Assembler::bcondAlways, *failure);
+  } else {
+    __ branch_optimized(Assembler::bcondAlways, *success);
+  }
+}
+
+void LIR_Assembler::emit_opTypeCheck(LIR_OpTypeCheck* op) {
+  LIR_Code code = op->code();
+  if (code == lir_store_check) {
+    Register value = op->object()->as_register();
+    Register array = op->array()->as_register();
+    Register k_RInfo = op->tmp1()->as_register();
+    Register klass_RInfo = op->tmp2()->as_register();
+    Register Rtmp1 = Z_R1_scratch;
+
+    CodeStub* stub = op->stub();
+
+    // Check if it needs to be profiled.
+    ciMethodData* md = NULL;
+    ciProfileData* data = NULL;
+
+    assert_different_registers(value, k_RInfo, klass_RInfo);
+
+    if (op->should_profile()) {
+      ciMethod* method = op->profiled_method();
+      assert(method != NULL, "Should have method");
+      int bci = op->profiled_bci();
+      md = method->method_data_or_null();
+      assert(md != NULL, "Sanity");
+      data = md->bci_to_data(bci);
+      assert(data != NULL,                "need data for type check");
+      assert(data->is_ReceiverTypeData(), "need ReceiverTypeData for type check");
+    }
+    NearLabel profile_cast_success, profile_cast_failure, done;
+    Label *success_target = op->should_profile() ? &profile_cast_success : &done;
+    Label *failure_target = op->should_profile() ? &profile_cast_failure : stub->entry();
+
+    if (op->should_profile()) {
+      NearLabel not_null;
+      __ compareU64_and_branch(value, (intptr_t) 0, Assembler::bcondNotEqual, not_null);
+      // Object is null; update MDO and exit.
+      Register mdo = klass_RInfo;
+      metadata2reg(md->constant_encoding(), mdo);
+      Address data_addr(mdo, md->byte_offset_of_slot(data, DataLayout::header_offset()));
+      int header_bits = DataLayout::flag_mask_to_header_mask(BitData::null_seen_byte_constant());
+      __ or2mem_8(data_addr, header_bits);
+      __ branch_optimized(Assembler::bcondAlways, done);
+      __ bind(not_null);
+    } else {
+      __ compareU64_and_branch(value, (intptr_t) 0, Assembler::bcondEqual, done);
+    }
+
+    add_debug_info_for_null_check_here(op->info_for_exception());
+    __ load_klass(k_RInfo, array);
+    __ load_klass(klass_RInfo, value);
+
+    // Get instance klass (it's already uncompressed).
+    __ z_lg(k_RInfo, Address(k_RInfo, ObjArrayKlass::element_klass_offset()));
+    // Perform the fast part of the checking logic.
+    __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL);
+    // Call out-of-line instance of __ check_klass_subtype_slow_path(...):
+    address a = Runtime1::entry_for (Runtime1::slow_subtype_check_id);
+    store_parameter(klass_RInfo, 0); // sub
+    store_parameter(k_RInfo, 1);     // super
+    emit_call_c(a); // Sets condition code 0 for match (2 otherwise).
+    CHECK_BAILOUT();
+    __ branch_optimized(Assembler::bcondNotEqual, *failure_target);
+    // Fall through to success case.
+
+    if (op->should_profile()) {
+      Register mdo = klass_RInfo, recv = k_RInfo;
+      assert_different_registers(value, mdo, recv);
+      __ bind(profile_cast_success);
+      metadata2reg(md->constant_encoding(), mdo);
+      __ load_klass(recv, value);
+      type_profile_helper(mdo, md, data, recv, Rtmp1, &done);
+      __ branch_optimized(Assembler::bcondAlways, done);
+
+      __ bind(profile_cast_failure);
+      metadata2reg(md->constant_encoding(), mdo);
+      __ add2mem_64(Address(mdo, md->byte_offset_of_slot(data, CounterData::count_offset())), -(int)DataLayout::counter_increment, Rtmp1);
+      __ branch_optimized(Assembler::bcondAlways, *stub->entry());
+    }
+
+    __ bind(done);
+  } else {
+    if (code == lir_checkcast) {
+      Register obj = op->object()->as_register();
+      Register dst = op->result_opr()->as_register();
+      NearLabel success;
+      emit_typecheck_helper(op, &success, op->stub()->entry(), &success);
+      __ bind(success);
+      __ lgr_if_needed(dst, obj);
+    } else {
+      if (code == lir_instanceof) {
+        Register obj = op->object()->as_register();
+        Register dst = op->result_opr()->as_register();
+        NearLabel success, failure, done;
+        emit_typecheck_helper(op, &success, &failure, &failure);
+        __ bind(failure);
+        __ clear_reg(dst);
+        __ branch_optimized(Assembler::bcondAlways, done);
+        __ bind(success);
+        __ load_const_optimized(dst, 1);
+        __ bind(done);
+      } else {
+        ShouldNotReachHere();
+      }
+    }
+  }
+}
+
+void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
+  Register addr = op->addr()->as_pointer_register();
+  Register t1_cmp = Z_R1_scratch;
+  if (op->code() == lir_cas_long) {
+    assert(VM_Version::supports_cx8(), "wrong machine");
+    Register cmp_value_lo = op->cmp_value()->as_register_lo();
+    Register new_value_lo = op->new_value()->as_register_lo();
+    __ z_lgr(t1_cmp, cmp_value_lo);
+    // Perform the compare and swap operation.
+    __ z_csg(t1_cmp, new_value_lo, 0, addr);
+  } else if (op->code() == lir_cas_int || op->code() == lir_cas_obj) {
+    Register cmp_value = op->cmp_value()->as_register();
+    Register new_value = op->new_value()->as_register();
+    if (op->code() == lir_cas_obj) {
+      if (UseCompressedOops) {
+                 t1_cmp = op->tmp1()->as_register();
+        Register t2_new = op->tmp2()->as_register();
+        assert_different_registers(cmp_value, new_value, addr, t1_cmp, t2_new);
+        __ oop_encoder(t1_cmp, cmp_value, true /*maybe null*/);
+        __ oop_encoder(t2_new, new_value, true /*maybe null*/);
+        __ z_cs(t1_cmp, t2_new, 0, addr);
+      } else {
+        __ z_lgr(t1_cmp, cmp_value);
+        __ z_csg(t1_cmp, new_value, 0, addr);
+      }
+    } else {
+      __ z_lr(t1_cmp, cmp_value);
+      __ z_cs(t1_cmp, new_value, 0, addr);
+    }
+  } else {
+    ShouldNotReachHere(); // new lir_cas_??
+  }
+}
+
+void LIR_Assembler::set_24bit_FPU() {
+  ShouldNotCallThis(); // x86 only
+}
+
+void LIR_Assembler::reset_FPU() {
+  ShouldNotCallThis(); // x86 only
+}
+
+void LIR_Assembler::breakpoint() {
+  Unimplemented();
+  //  __ breakpoint_trap();
+}
+
+void LIR_Assembler::push(LIR_Opr opr) {
+  ShouldNotCallThis(); // unused
+}
+
+void LIR_Assembler::pop(LIR_Opr opr) {
+  ShouldNotCallThis(); // unused
+}
+
+void LIR_Assembler::monitor_address(int monitor_no, LIR_Opr dst_opr) {
+  Address addr = frame_map()->address_for_monitor_lock(monitor_no);
+  __ add2reg(dst_opr->as_register(), addr.disp(), addr.base());
+}
+
+void LIR_Assembler::emit_lock(LIR_OpLock* op) {
+  Register obj = op->obj_opr()->as_register();  // May not be an oop.
+  Register hdr = op->hdr_opr()->as_register();
+  Register lock = op->lock_opr()->as_register();
+  if (!UseFastLocking) {
+    __ branch_optimized(Assembler::bcondAlways, *op->stub()->entry());
+  } else if (op->code() == lir_lock) {
+    assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
+    // Add debug info for NullPointerException only if one is possible.
+    if (op->info() != NULL) {
+      add_debug_info_for_null_check_here(op->info());
+    }
+    __ lock_object(hdr, obj, lock, *op->stub()->entry());
+    // done
+  } else if (op->code() == lir_unlock) {
+    assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
+    __ unlock_object(hdr, obj, lock, *op->stub()->entry());
+  } else {
+    ShouldNotReachHere();
+  }
+  __ bind(*op->stub()->continuation());
+}
+
+void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
+  ciMethod* method = op->profiled_method();
+  int bci          = op->profiled_bci();
+  ciMethod* callee = op->profiled_callee();
+
+  // Update counter for all call types.
+  ciMethodData* md = method->method_data_or_null();
+  assert(md != NULL, "Sanity");
+  ciProfileData* data = md->bci_to_data(bci);
+  assert(data->is_CounterData(), "need CounterData for calls");
+  assert(op->mdo()->is_single_cpu(),  "mdo must be allocated");
+  Register mdo  = op->mdo()->as_register();
+  assert(op->tmp1()->is_double_cpu(), "tmp1 must be allocated");
+  Register tmp1 = op->tmp1()->as_register_lo();
+  metadata2reg(md->constant_encoding(), mdo);
+
+  Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
+  Bytecodes::Code bc = method->java_code_at_bci(bci);
+  const bool callee_is_static = callee->is_loaded() && callee->is_static();
+  // Perform additional virtual call profiling for invokevirtual and
+  // invokeinterface bytecodes.
+  if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
+      !callee_is_static &&  // Required for optimized MH invokes.
+      C1ProfileVirtualCalls) {
+    assert(op->recv()->is_single_cpu(), "recv must be allocated");
+    Register recv = op->recv()->as_register();
+    assert_different_registers(mdo, tmp1, recv);
+    assert(data->is_VirtualCallData(), "need VirtualCallData for virtual calls");
+    ciKlass* known_klass = op->known_holder();
+    if (C1OptimizeVirtualCallProfiling && known_klass != NULL) {
+      // We know the type that will be seen at this call site; we can
+      // statically update the MethodData* rather than needing to do
+      // dynamic tests on the receiver type.
+
+      // NOTE: we should probably put a lock around this search to
+      // avoid collisions by concurrent compilations.
+      ciVirtualCallData* vc_data = (ciVirtualCallData*) data;
+      uint i;
+      for (i = 0; i < VirtualCallData::row_limit(); i++) {
+        ciKlass* receiver = vc_data->receiver(i);
+        if (known_klass->equals(receiver)) {
+          Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
+          __ add2mem_64(data_addr, DataLayout::counter_increment, tmp1);
+          return;
+        }
+      }
+
+      // Receiver type not found in profile data. Select an empty slot.
+
+      // Note that this is less efficient than it should be because it
+      // always does a write to the receiver part of the
+      // VirtualCallData rather than just the first time.
+      for (i = 0; i < VirtualCallData::row_limit(); i++) {
+        ciKlass* receiver = vc_data->receiver(i);
+        if (receiver == NULL) {
+          Address recv_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_offset(i)));
+          metadata2reg(known_klass->constant_encoding(), tmp1);
+          __ z_stg(tmp1, recv_addr);
+          Address data_addr(mdo, md->byte_offset_of_slot(data, VirtualCallData::receiver_count_offset(i)));
+          __ add2mem_64(data_addr, DataLayout::counter_increment, tmp1);
+          return;
+        }
+      }
+    } else {
+      __ load_klass(recv, recv);
+      NearLabel update_done;
+      type_profile_helper(mdo, md, data, recv, tmp1, &update_done);
+      // Receiver did not match any saved receiver and there is no empty row for it.
+      // Increment total counter to indicate polymorphic case.
+      __ add2mem_64(counter_addr, DataLayout::counter_increment, tmp1);
+      __ bind(update_done);
+    }
+  } else {
+    // static call
+    __ add2mem_64(counter_addr, DataLayout::counter_increment, tmp1);
+  }
+}
+
+void LIR_Assembler::align_backward_branch_target() {
+  __ align(OptoLoopAlignment);
+}
+
+void LIR_Assembler::emit_delay(LIR_OpDelay* op) {
+  ShouldNotCallThis(); // There are no delay slots on ZARCH_64.
+}
+
+void LIR_Assembler::negate(LIR_Opr left, LIR_Opr dest) {
+  assert(left->is_register(), "can only handle registers");
+
+  if (left->is_single_cpu()) {
+    __ z_lcr(dest->as_register(), left->as_register());
+  } else if (left->is_single_fpu()) {
+    __ z_lcebr(dest->as_float_reg(), left->as_float_reg());
+  } else if (left->is_double_fpu()) {
+    __ z_lcdbr(dest->as_double_reg(), left->as_double_reg());
+  } else {
+    assert(left->is_double_cpu(), "Must be a long");
+    __ z_lcgr(dest->as_register_lo(), left->as_register_lo());
+  }
+}
+
+void LIR_Assembler::fxch(int i) {
+  ShouldNotCallThis(); // x86 only
+}
+
+void LIR_Assembler::fld(int i) {
+  ShouldNotCallThis(); // x86 only
+}
+
+void LIR_Assembler::ffree(int i) {
+  ShouldNotCallThis(); // x86 only
+}
+
+void LIR_Assembler::rt_call(LIR_Opr result, address dest,
+                            const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
+  assert(!tmp->is_valid(), "don't need temporary");
+  emit_call_c(dest);
+  CHECK_BAILOUT();
+  if (info != NULL) {
+    add_call_info_here(info);
+  }
+}
+
+void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {
+  ShouldNotCallThis(); // not needed on ZARCH_64
+}
+
+void LIR_Assembler::membar() {
+  __ z_fence();
+}
+
+void LIR_Assembler::membar_acquire() {
+  __ z_acquire();
+}
+
+void LIR_Assembler::membar_release() {
+  __ z_release();
+}
+
+void LIR_Assembler::membar_loadload() {
+  __ z_acquire();
+}
+
+void LIR_Assembler::membar_storestore() {
+  __ z_release();
+}
+
+void LIR_Assembler::membar_loadstore() {
+  __ z_acquire();
+}
+
+void LIR_Assembler::membar_storeload() {
+  __ z_fence();
+}
+
+void LIR_Assembler::on_spin_wait() {
+  Unimplemented();
+}
+
+void LIR_Assembler::leal(LIR_Opr addr_opr, LIR_Opr dest) {
+  LIR_Address* addr = addr_opr->as_address_ptr();
+  assert(addr->scale() == LIR_Address::times_1, "scaling unsupported");
+  __ load_address(dest->as_pointer_register(), as_Address(addr));
+}
+
+void LIR_Assembler::get_thread(LIR_Opr result_reg) {
+  ShouldNotCallThis(); // unused
+}
+
+#ifdef ASSERT
+// Emit run-time assertion.
+void LIR_Assembler::emit_assert(LIR_OpAssert* op) {
+  Unimplemented();
+}
+#endif
+
+void LIR_Assembler::peephole(LIR_List*) {
+  // Do nothing for now.
+}
+
+void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) {
+  assert(code == lir_xadd, "lir_xchg not supported");
+  Address src_addr = as_Address(src->as_address_ptr());
+  Register base = src_addr.base();
+  intptr_t disp = src_addr.disp();
+  if (src_addr.index()->is_valid()) {
+    // LAA and LAAG do not support index register.
+    __ load_address(Z_R1_scratch, src_addr);
+    base = Z_R1_scratch;
+    disp = 0;
+  }
+  if (data->type() == T_INT) {
+    __ z_laa(dest->as_register(), data->as_register(), disp, base);
+  } else if (data->type() == T_LONG) {
+    assert(data->as_register_lo() == data->as_register_hi(), "should be a single register");
+    __ z_laag(dest->as_register_lo(), data->as_register_lo(), disp, base);
+  } else {
+    ShouldNotReachHere();
+  }
+}
+
+void LIR_Assembler::emit_profile_type(LIR_OpProfileType* op) {
+  Register obj = op->obj()->as_register();
+  Register tmp1 = op->tmp()->as_pointer_register();
+  Register tmp2 = Z_R1_scratch;
+  Address mdo_addr = as_Address(op->mdp()->as_address_ptr());
+  ciKlass* exact_klass = op->exact_klass();
+  intptr_t current_klass = op->current_klass();
+  bool not_null = op->not_null();
+  bool no_conflict = op->no_conflict();
+
+  Label update, next, none, null_seen, init_klass;
+
+  bool do_null = !not_null;
+  bool exact_klass_set = exact_klass != NULL && ciTypeEntries::valid_ciklass(current_klass) == exact_klass;
+  bool do_update = !TypeEntries::is_type_unknown(current_klass) && !exact_klass_set;
+
+  assert(do_null || do_update, "why are we here?");
+  assert(!TypeEntries::was_null_seen(current_klass) || do_update, "why are we here?");
+
+  __ verify_oop(obj);
+
+  if (do_null || tmp1 != obj DEBUG_ONLY(|| true)) {
+    __ z_ltgr(tmp1, obj);
+  }
+  if (do_null) {
+    __ z_brnz(update);
+    if (!TypeEntries::was_null_seen(current_klass)) {
+      __ z_lg(tmp1, mdo_addr);
+      __ z_oill(tmp1, TypeEntries::null_seen);
+      __ z_stg(tmp1, mdo_addr);
+    }
+    if (do_update) {
+      __ z_bru(next);
+    }
+  } else {
+    __ asm_assert_ne("unexpect null obj", __LINE__);
+  }
+
+  __ bind(update);
+
+  if (do_update) {
+#ifdef ASSERT
+    if (exact_klass != NULL) {
+      __ load_klass(tmp1, tmp1);
+      metadata2reg(exact_klass->constant_encoding(), tmp2);
+      __ z_cgr(tmp1, tmp2);
+      __ asm_assert_eq("exact klass and actual klass differ", __LINE__);
+    }
+#endif
+
+    Label do_update;
+    __ z_lg(tmp2, mdo_addr);
+
+    if (!no_conflict) {
+      if (exact_klass == NULL || TypeEntries::is_type_none(current_klass)) {
+        if (exact_klass != NULL) {
+          metadata2reg(exact_klass->constant_encoding(), tmp1);
+        } else {
+          __ load_klass(tmp1, tmp1);
+        }
+
+        // Klass seen before: nothing to do (regardless of unknown bit).
+        __ z_lgr(Z_R0_scratch, tmp2);
+        assert(Immediate::is_uimm(~TypeEntries::type_klass_mask, 16), "or change following instruction");
+        __ z_nill(Z_R0_scratch, TypeEntries::type_klass_mask & 0xFFFF);
+        __ compareU64_and_branch(Z_R0_scratch, tmp1, Assembler::bcondEqual, next);
+
+        // Already unknown: Nothing to do anymore.
+        __ z_tmll(tmp2, TypeEntries::type_unknown);
+        __ z_brc(Assembler::bcondAllOne, next);
+
+        if (TypeEntries::is_type_none(current_klass)) {
+          __ z_lgr(Z_R0_scratch, tmp2);
+          assert(Immediate::is_uimm(~TypeEntries::type_mask, 16), "or change following instruction");
+          __ z_nill(Z_R0_scratch, TypeEntries::type_mask & 0xFFFF);
+          __ compareU64_and_branch(Z_R0_scratch, (intptr_t)0, Assembler::bcondEqual, init_klass);
+        }
+      } else {
+        assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
+               ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
+
+        // Already unknown: Nothing to do anymore.
+        __ z_tmll(tmp2, TypeEntries::type_unknown);
+        __ z_brc(Assembler::bcondAllOne, next);
+      }
+
+      // Different than before. Cannot keep accurate profile.
+      __ z_oill(tmp2, TypeEntries::type_unknown);
+      __ z_bru(do_update);
+    } else {
+      // There's a single possible klass at this profile point.
+      assert(exact_klass != NULL, "should be");
+      if (TypeEntries::is_type_none(current_klass)) {
+        metadata2reg(exact_klass->constant_encoding(), tmp1);
+        __ z_lgr(Z_R0_scratch, tmp2);
+        assert(Immediate::is_uimm(~TypeEntries::type_klass_mask, 16), "or change following instruction");
+        __ z_nill(Z_R0_scratch, TypeEntries::type_klass_mask & 0xFFFF);
+        __ compareU64_and_branch(Z_R0_scratch, tmp1, Assembler::bcondEqual, next);
+#ifdef ASSERT
+        {
+          Label ok;
+          __ z_lgr(Z_R0_scratch, tmp2);
+          assert(Immediate::is_uimm(~TypeEntries::type_mask, 16), "or change following instruction");
+          __ z_nill(Z_R0_scratch, TypeEntries::type_mask & 0xFFFF);
+          __ compareU64_and_branch(Z_R0_scratch, (intptr_t)0, Assembler::bcondEqual, ok);
+          __ stop("unexpected profiling mismatch");
+          __ bind(ok);
+        }
+#endif
+
+      } else {
+        assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
+               ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
+
+        // Already unknown: Nothing to do anymore.
+        __ z_tmll(tmp2, TypeEntries::type_unknown);
+        __ z_brc(Assembler::bcondAllOne, next);
+        __ z_oill(tmp2, TypeEntries::type_unknown);
+        __ z_bru(do_update);
+      }
+    }
+
+    __ bind(init_klass);
+    // Combine klass and null_seen bit (only used if (tmp & type_mask)==0).
+    __ z_ogr(tmp2, tmp1);
+
+    __ bind(do_update);
+    __ z_stg(tmp2, mdo_addr);
+
+    __ bind(next);
+  }
+}
+
+void LIR_Assembler::emit_updatecrc32(LIR_OpUpdateCRC32* op) {
+  assert(op->crc()->is_single_cpu(), "crc must be register");
+  assert(op->val()->is_single_cpu(), "byte value must be register");
+  assert(op->result_opr()->is_single_cpu(), "result must be register");
+  Register crc = op->crc()->as_register();
+  Register val = op->val()->as_register();
+  Register res = op->result_opr()->as_register();
+
+  assert_different_registers(val, crc, res);
+
+  __ load_const_optimized(res, StubRoutines::crc_table_addr());
+  __ not_(crc, noreg, false); // ~crc
+  __ update_byte_crc32(crc, val, res);
+  __ not_(res, crc, false); // ~crc
+}
+
+#undef __
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_LIRAssembler_s390.hpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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.
+ *
+ */
+
+#ifndef CPU_S390_VM_C1_LIRASSEMBLER_S390_HPP
+#define CPU_S390_VM_C1_LIRASSEMBLER_S390_HPP
+
+ private:
+
+  // Record the type of the receiver in ReceiverTypeData.
+  void type_profile_helper(Register mdo, ciMethodData *md, ciProfileData *data,
+                           Register recv, Register tmp1, Label* update_done);
+  // Setup pointers to MDO, MDO slot, also compute offset bias to access the slot.
+  void setup_md_access(ciMethod* method, int bci,
+                       ciMethodData*& md, ciProfileData*& data, int& mdo_offset_bias);
+ public:
+  address emit_call_c(address a);
+
+  void store_parameter(Register r, int param_num);
+  void store_parameter(jint     c, int param_num);
+
+  void check_reserved_argument_area(int bytes) {
+    assert(bytes + FrameMap::first_available_sp_in_frame <= frame_map()->reserved_argument_area_size(),
+           "reserved_argument_area too small");
+  }
+
+  enum {
+    call_stub_size = 512, // See Compile::MAX_stubs_size and CompiledStaticCall::emit_to_interp_stub.
+    exception_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(128),
+    deopt_handler_size = DEBUG_ONLY(1*K) NOT_DEBUG(64)
+  };
+
+#endif // CPU_S390_VM_C1_LIRASSEMBLER_S390_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/s390/vm/c1_LIRGenerator_s390.cpp	Thu Oct 13 14:49:34 2016 +0200
@@ -0,0 +1,1246 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016 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 "precompiled.hpp"
+#include "c1/c1_Compilation.hpp"
+#include "c1/c1_FrameMap.hpp"
+#include "c1/c1_Instruction.hpp"
+#include "c1/c1_LIRAssembler.hpp"
+#include "c1/c1_LIRGenerator.hpp"
+#include "c1/c1_Runtime1.hpp"
+#include "c1/c1_ValueStack.hpp"
+#include "ci/ciArray.hpp"
+#include "ci/ciObjArrayKlass.hpp"
+#include "ci/ciTypeArrayKlass.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "vmreg_s390.inline.hpp"
+
+#ifdef ASSERT
+#define __ gen()->lir(__FILE__, __LINE__)->
+#else
+#define __ gen()->lir()->
+#endif
+
+void LIRItem::load_byte_item() {
+  // Byte loads use same registers as other loads.
+  load_item();
+}
+
+void LIRItem::load_nonconstant(int bits) {
+  LIR_Opr r = value()->operand();
+  if (_gen->can_inline_as_constant(value(), bits)) {
+    if (!r->is_constant()) {
+      r = LIR_OprFact::value_type(value()->type());
+    }
+    _result = r;
+  } else {
+    load_item();
+  }
+}
+
+inline void load_int_as_long(LIR_List *ll, LIRItem &li, LIR_Opr dst) {
+  LIR_Opr r = li.value()->operand();
+  if (r->is_constant()) {
+    // Constants get loaded with sign extend on this platform.
+    ll->move(li.result(), dst);
+  } else {
+    if (!r->is_register()) {
+      li.load_item_force(dst);
+    }
+    LIR_Opr dst_l = FrameMap::as_long_opr(dst->as_register());
+    ll->convert(Bytecodes::_i2l, li.result(), dst_l); // Convert.
+  }
+}
+
+//--------------------------------------------------------------
+//               LIRGenerator
+//--------------------------------------------------------------
+
+LIR_Opr LIRGenerator::exceptionOopOpr() { return FrameMap::as_oop_opr(Z_EXC_OOP); }
+LIR_Opr LIRGenerator::exceptionPcOpr()  { return FrameMap::as_opr(Z_EXC_PC); }
+LIR_Opr LIRGenerator::divInOpr()        { return FrameMap::Z_R11_opr; }
+LIR_Opr LIRGenerator::divOutOpr()       { return FrameMap::Z_R11_opr; }
+LIR_Opr LIRGenerator::remOutOpr()       { return FrameMap::Z_R10_opr; }
+LIR_Opr LIRGenerator::ldivInOpr()       { return FrameMap::Z_R11_long_opr; }
+LIR_Opr LIRGenerator::ldivOutOpr()      { return FrameMap::Z_R11_long_opr; }
+LIR_Opr LIRGenerator::lremOutOpr()      { return FrameMap::Z_R10_long_opr; }
+LIR_Opr LIRGenerator::syncLockOpr()     { return new_register(T_INT); }
+LIR_Opr LIRGenerator::syncTempOpr()     { return FrameMap::Z_R13_opr; }
+LIR_Opr LIRGenerator::getThreadTemp()   { return LIR_OprFact::illegalOpr; }
+
+LIR_Opr LIRGenerator::result_register_for (ValueType* type, bool callee) {
+  LIR_Opr opr;
+  switch (type->tag()) {
+    case intTag:    opr = FrameMap::Z_R2_opr;        break;
+    case objectTag: opr = FrameMap::Z_R2_oop_opr;    break;
+    case longTag:   opr = FrameMap::Z_R2_long_opr;   break;
+    case floatTag:  opr = FrameMap::Z_F0_opr;        break;
+    case doubleTag: opr = FrameMap::Z_F0_double_opr; break;
+
+    case addressTag:
+    default: ShouldNotReachHere(); return LIR_OprFact::illegalOpr;
+  }
+
+  assert(opr->type_field() == as_OprType(as_BasicType(type)), "type mismatch");
+  return opr;
+}
+
+LIR_Opr LIRGenerator::rlock_byte(BasicType type) {
+  return new_register(T_INT);
+}
+
+//--------- Loading items into registers. --------------------------------
+
+// z/Architecture cannot inline all constants.
+bool LIRGenerator::can_store_as_constant(Value v, BasicType type) const {
+  if (v->type()->as_IntConstant() != NULL) {
+    return Immediate::is_simm16(v->type()->as_IntConstant()->value());
+  } else if (v->type()->as_LongConstant() != NULL) {
+    return Immediate::is_simm16(v->type()->as_LongConstant()->value());
+  } else if (v->type()->as_ObjectConstant() != NULL) {
+    return v->type()->as_ObjectConstant()->value()->is_null_object();
+  } else {
+    return false;
+  }
+}
+
+bool LIRGenerator::can_inline_as_constant(Value i, int bits) const {
+  if (i->type()->as_IntConstant() != NULL) {
+    return Assembler::is_simm(i->type()->as_IntConstant()->value(), bits);
+  } else if (i->type()->as_LongConstant() != NULL) {
+    return Assembler::is_simm(i->type()->as_LongConstant()->value(), bits);
+  } else {
+    return can_store_as_constant(i, as_BasicType(i->type()));
+  }
+}
+
+bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const {
+  if (c->type() == T_INT) {
+    return Immediate::is_simm20(c->as_jint());
+  } else   if (c->type() == T_LONG) {
+    return Immediate::is_simm20(c->as_jlong());
+  }
+  return false;
+}
+
+LIR_Opr LIRGenerator::safepoint_poll_register() {
+  return new_register(longType);
+}
+
+LIR_Address* LIRGenerator::generate_address(LIR_Opr base, LIR_Opr index,
+                                            int shift, int disp, BasicType type) {
+  assert(base->is_register(), "must be");
+  if (index->is_constant()) {
+    intptr_t large_disp = ((intx)(index->as_constant_ptr()->as_jint()) << shift) + disp;
+    if (Displacement::is_validDisp(large_disp)) {
+      return new LIR_Address(base, large_disp, type);
+    }
+    // Index is illegal so replace it with the displacement loaded into a register.
+    index = new_pointer_register();
+    __ move(LIR_OprFact::intptrConst(large_disp), index);
+    return new LIR_Address(base, index, type);
+  } else {
+    if (shift > 0) {
+      LIR_Opr tmp = new_pointer_register();
+      __ shift_left(index, shift, tmp);
+      index = tmp;
+    }
+    return new LIR_Address(base, index, disp, type);
+  }
+}
+
+LIR_Address* LIRGenerator::emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr,
+                                              BasicType type, bool needs_card_mark) {
+  int elem_size = type2aelembytes(type);
+  int shift = exact_log2(elem_size);
+  int offset_in_bytes = arrayOopDesc::base_offset_in_bytes(type);
+
+  LIR_Address* addr;
+  if (index_opr->is_constant()) {
+    addr = new LIR_Address(array_opr,
+                           offset_in_bytes + (intx)(index_opr->as_jint()) * elem_size, type);
+  } else {
+    if (index_opr->type() == T_INT) {
+      LIR_Opr tmp = new_register(T_LONG);
+      __ convert(Bytecodes::_i2l, index_opr, tmp);
+      index_opr = tmp;
+    }
+    if (shift > 0) {
+      __ shift_left(index_opr, shift, index_opr);
+    }
+    addr = new LIR_Address(array_opr,
+                           index_opr,
+                           offset_in_bytes, type);
+  }
+  if (needs_card_mark) {
+    // This store will need a precise card mark, so go ahead and
+    // compute the full adddres instead of computing once for the
+    // store and again for the card mark.
+    LIR_Opr tmp = new_pointer_register();
+    __ leal(LIR_OprFact::address(addr), tmp);
+    return new LIR_Address(tmp, type);
+  } else {
+    return addr;
+  }
+}
+
+LIR_Opr LIRGenerator::load_immediate(int x, BasicType type) {
+  LIR_Opr r = LIR_OprFact::illegalOpr;
+  if (type == T_LONG) {
+    r = LIR_OprFact::longConst(x);
+  } else if (type == T_INT) {
+    r = LIR_OprFact::intConst(x);
+  } else {
+    ShouldNotReachHere();
+  }
+  return r;
+}
+
+void LIRGenerator::increment_counter(address counter, BasicType type, int step) {
+  LIR_Opr pointer = new_pointer_register();
+  __ move(LIR_OprFact::intptrConst(counter), pointer);
+  LIR_Address* addr = new LIR_Address(pointer, type);
+  increment_counter(addr, step);
+}
+
+void LIRGenerator::increment_counter(LIR_Address* addr, int step) {
+  __ add((LIR_Opr)addr, LIR_OprFact::intConst(step), (LIR_Opr)addr);
+}
+
+void LIRGenerator::cmp_mem_int(LIR_Condition condition, LIR_Opr base, int disp, int c, CodeEmitInfo* info) {
+  LIR_Opr scratch = FrameMap::Z_R1_opr;
+  __ load(new LIR_Address(base, disp, T_INT), scratch, info);
+  __ cmp(condition, scratch, c);
+}
+
+void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, int disp, BasicType type, CodeEmitInfo* info) {
+  __ cmp_reg_mem(condition, reg, new LIR_Address(base, disp, type), info);
+}
+
+void LIRGenerator::cmp_reg_mem(LIR_Condition condition, LIR_Opr reg, LIR_Opr base, LIR_Opr disp, BasicType type, CodeEmitInfo* info) {
+  __ cmp_reg_mem(condition, reg, new LIR_Address(base, disp, type), info);
+}
+
+bool LIRGenerator::strength_reduce_multiply(LIR_Opr left, int c, LIR_Opr result, LIR_Opr tmp) {
+  if (tmp->is_valid()) {
+    if (is_power_of_2(c + 1)) {
+      __ move(left, tmp);
+      __ shift_left(left, log2_intptr(c + 1), left);
+      __ sub(left, tmp, result);
+      return true;
+    } else if (is_power_of_2(c - 1)) {
+      __ move(left, tmp);
+      __ shift_left(left, log2_intptr(c - 1), left);
+      __ add(left, tmp, result);
+      return true;
+    }
+  }
+  return false;
+}
+
+void LIRGenerator::store_stack_parameter (LIR_Opr item, ByteSize offset_from_sp) {
+  BasicType type = item->type();
+  __ store(item, new LIR_Address(FrameMap::Z_SP_opr, in_bytes(offset_from_sp), type));
+}
+
+//----------------------------------------------------------------------
+//             visitor functions
+//----------------------------------------------------------------------
+
+void LIRGenerator::do_StoreIndexed(StoreIndexed* x) {
+  assert(x->is_pinned(),"");
+  bool needs_range_check = x->compute_needs_range_check();
+  bool use_length = x->length() != NULL;
+  bool obj_store = x->elt_type() == T_ARRAY || x->elt_type() == T_OBJECT;
+  bool needs_store_check = obj_store && (x->value()->as_Constant() == NULL ||
+                                         !get_jobject_constant(x->value())->is_null_object() ||
+                                         x->should_profile());
+
+  LIRItem array(x->array(), this);
+  LIRItem index(x->index(), this);
+  LIRItem value(x->value(), this);
+  LIRItem length(this);
+
+  array.load_item();
+  index.load_nonconstant(20);
+
+  if (use_length && needs_range_check) {
+    length.set_instruction(x->length());
+    length.load_item();
+  }
+  if (needs_store_check) {
+    value.load_item();
+  } else {
+    value.load_for_store(x->elt_type());
+  }
+
+  set_no_result(x);
+
+  // The CodeEmitInfo must be duplicated for each different
+  // LIR-instruction because spilling can occur anywhere between two
+  // instructions and so the debug information must be different.
+  CodeEmitInfo* range_check_info = state_for (x);
+  CodeEmitInfo* null_check_info = NULL;
+  if (x->needs_null_check()) {
+    null_check_info = new CodeEmitInfo(range_check_info);
+  }
+
+  // Emit array address setup early so it schedules better.
+  LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);
+  if (value.result()->is_constant() && array_addr->index()->is_valid()) {
+    // Constants cannot be stored with index register on ZARCH_64 (see LIR_Assembler::const2mem()).
+    LIR_Opr tmp = new_pointer_register();
+    __ leal(LIR_OprFact::address(array_addr), tmp);
+    array_addr = new LIR_Address(tmp, x->elt_type());
+  }
+
+  if (GenerateRangeChecks && needs_range_check) {
+    if (use_length) {
+      __ cmp(lir_cond_belowEqual, length.result(), index.result());
+      __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
+    } else {
+      array_range_check(array.result(), index.result(), null_check_info, range_check_info);
+      // Range_check also does the null check.
+      null_check_info = NULL;
+    }
+  }
+
+  if (GenerateArrayStoreCheck && needs_store_check) {
+    LIR_Opr tmp1 = new_register(objectType);
+    LIR_Opr tmp2 = new_register(objectType);
+    LIR_Opr tmp3 = LIR_OprFact::illegalOpr;
+
+    CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);
+    __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());
+  }
+
+  if (obj_store) {
+    // Needs GC write barriers.
+    pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
+                true /* do_load */, false /* patch */, NULL);
+    __ move(value.result(), array_addr, null_check_info);
+    // Seems to be a precise.
+    post_barrier(LIR_OprFact::address(array_addr), value.result());
+  } else {
+    __ move(value.result(), array_addr, null_check_info);
+  }
+}
+
+void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
+  assert(x->is_pinned(),"");
+  LIRItem obj(x->obj(), this);
+  obj.load_item();
+
+  set_no_result(x);
+
+  // "lock" stores the address of the monitor stack slot, so this is not an oop.
+  LIR_Opr lock = new_register(T_INT);
+
+  CodeEmitInfo* info_for_exception = NULL;
+  if (x->needs_null_check()) {
+    info_for_exception = state_for (x);
+  }
+  // This CodeEmitInfo must not have the xhandlers because here the
+  // object is already locked (xhandlers expect object to be unlocked).
+  CodeEmitInfo* info = state_for (x, x->state(), true);
+  monitor_enter(obj.result(), lock, syncTempOpr(), LIR_OprFact::illegalOpr,
+                x->monitor_no(), info_for_exception, info);
+}
+
+void LIRGenerator::do_MonitorExit(MonitorExit* x) {
+  assert(x->is_pinned(),"");
+
+  LIRItem obj(x->obj(), this);
+  obj.dont_load_item();
+
+  LIR_Opr lock = new_register(T_INT);
+  LIR_Opr obj_temp = new_register(T_INT);
+  set_no_result(x);
+  monitor_exit(obj_temp, lock, syncTempOpr(), LIR_OprFact::illegalOpr, x->monitor_no());
+}
+
+// _ineg, _lneg, _fneg, _dneg
+void LIRGenerator::do_NegateOp(NegateOp* x) {
+  LIRItem value(x->x(), this);
+  value.load_item();
+  LIR_Opr reg = rlock_result(x);
+  __ negate(value.result(), reg);
+}
+
+// for _fadd, _fmul, _fsub, _fdiv, _frem
+//     _dadd, _dmul, _dsub, _ddiv, _drem
+void LIRGenerator::do_ArithmeticOp_FPU(ArithmeticOp* x) {
+  LIRItem left(x->x(),  this);
+  LIRItem right(x->y(), this);
+  LIRItem* left_arg  = &left;
+  LIRItem* right_arg = &right;
+  assert(!left.is_stack(), "can't both be memory operands");
+  left.load_item();
+
+  if (right.is_register() || right.is_constant()) {
+    right.load_item();
+  } else {
+    right.dont_load_item();
+  }
+
+  if ((x->op() == Bytecodes::_frem) || (x->op() == Bytecodes::_drem)) {
+    address entry;
+    switch (x->op()) {
+    case Bytecodes::_frem:
+      entry = CAST_FROM_FN_PTR(address, SharedRuntime::frem);
+      break;
+    case Bytecodes::_drem:
+      entry = CAST_FROM_FN_PTR(address, SharedRuntime::drem);
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+    LIR_Opr result = call_runtime(x->x(), x->y(), entry, x->type(), NULL);
+    set_result(x, result);