From 38291f5d680e9348dbd5d49eef50cedf384bdc10 Mon Sep 17 00:00:00 2001
Date: Sat, 23 May 2026 11:53:44 +0800
Subject: [PATCH] Add UTF Conversion Intrinsics

---
 make/hotspot/lib/JvmFlags.gmk                 |    5 +
 src/hotspot/cpu/aarch64/aarch64.ad            |   52 +
 src/hotspot/cpu/aarch64/globals_aarch64.hpp   |    2 +
 .../cpu/aarch64/macroAssembler_aarch64.cpp    |  672 +++++++
 .../cpu/aarch64/macroAssembler_aarch64.hpp    |   17 +
 .../cpu/aarch64/simdutf_utf_tables.hpp        | 1602 +++++++++++++++++
 .../cpu/aarch64/stubDeclarations_aarch64.hpp  |    8 +
 .../cpu/aarch64/stubGenerator_aarch64.cpp     |  607 +++++++
 .../cpu/aarch64/stubRoutines_aarch64.cpp      |    6 +
 .../cpu/aarch64/stubRoutines_aarch64.hpp      |   20 +
 src/hotspot/share/adlc/formssel.cpp           |    4 +-
 src/hotspot/share/classfile/javaClasses.cpp   |   24 +
 src/hotspot/share/classfile/javaClasses.hpp   |    4 +
 src/hotspot/share/classfile/vmIntrinsics.cpp  |    2 +
 src/hotspot/share/classfile/vmIntrinsics.hpp  |    6 +
 src/hotspot/share/classfile/vmSymbols.hpp     |    1 +
 .../gc/shenandoah/c2/shenandoahSupport.cpp    |    4 +
 src/hotspot/share/jvmci/vmStructs_jvmci.cpp   |    2 +
 src/hotspot/share/legal/simdutf.md            |  237 +++
 src/hotspot/share/opto/c2compiler.cpp         |    6 +
 src/hotspot/share/opto/classes.hpp            |    2 +
 src/hotspot/share/opto/escape.cpp             |   35 +-
 src/hotspot/share/opto/intrinsicnode.cpp      |   40 +
 src/hotspot/share/opto/intrinsicnode.hpp      |   34 +
 src/hotspot/share/opto/lcm.cpp                |    2 +
 src/hotspot/share/opto/library_call.cpp       |  100 +-
 src/hotspot/share/opto/library_call.hpp       |    2 +
 src/hotspot/share/opto/loopTransform.cpp      |    4 +
 src/hotspot/share/opto/macro.cpp              |    6 +-
 src/hotspot/share/opto/matcher.cpp            |    6 +
 src/hotspot/share/runtime/threads.cpp         |    6 +-
 .../share/classes/java/lang/String.java       |   77 +-
 .../share/classes/java/lang/StringCoding.java |  197 +-
 .../cs/TestStringCodingUTF8Intrinsics.java    |  307 ++++
 .../java/lang/StringCodingUTF8Intrinsics.java |   61 +
 35 files changed, 4119 insertions(+), 41 deletions(-)
 create mode 100644 src/hotspot/cpu/aarch64/simdutf_utf_tables.hpp
 create mode 100644 src/hotspot/share/legal/simdutf.md
 create mode 100644 test/jdk/sun/nio/cs/TestStringCodingUTF8Intrinsics.java
 create mode 100644 test/micro/org/openjdk/bench/java/lang/StringCodingUTF8Intrinsics.java

diff --git a/make/hotspot/lib/JvmFlags.gmk b/make/hotspot/lib/JvmFlags.gmk
index 57b632ee5..eb7c111df 100644
--- a/make/hotspot/lib/JvmFlags.gmk
+++ b/make/hotspot/lib/JvmFlags.gmk
@@ -43,6 +43,11 @@ JVM_SRC_DIRS += $(call uniq, $(wildcard $(foreach d, $(JVM_SRC_ROOTS), \
     $(JVM_VARIANT_OUTPUTDIR)/gensrc
     #
 
+JVM_ACC_PLUGIN_SRC := $(TOPDIR)/src/java.base/share/native/libjplugin/feature
+ifeq ($(wildcard $(JVM_ACC_PLUGIN_SRC)), $(JVM_ACC_PLUGIN_SRC))
+  JVM_SRC_DIRS += $(JVM_ACC_PLUGIN_SRC)
+endif
+
 JVM_CFLAGS_INCLUDES += \
     $(patsubst %,-I%,$(JVM_SRC_DIRS)) \
     -I$(TOPDIR)/src/hotspot/share/include \
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index 423da32d6..75cbc63a8 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -17317,6 +17317,58 @@ instruct convHF2SAndHF2F(vRegF dst, vRegF src)
   ins_pipe(pipe_slow);
 %}
 
+// encode char[] to byte[] in UTF8
+instruct encode_utf8_from_utf16(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
+                                vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
+                                vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
+                                vRegD_V6 vtmp6, vRegD_V7 vtmp7, vRegD_V12 vtmp8,
+                                vRegD_V13 vtmp9, iRegI_R0 result, rFlagsReg cr)
+%{
+  match(Set result (EncodeUtf8FromUtf16 src (Binary dst len)));
+  effect(USE_KILL src, USE_KILL dst, USE_KILL len, TEMP vtmp0, TEMP vtmp1,
+         TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP vtmp7,
+         TEMP vtmp8, TEMP vtmp9, KILL cr);
+
+  format %{ "Encode UTF8 from UTF16 $src, $dst, $len -> $result # KILL $src $dst V0-V9 cr" %}
+  ins_encode %{
+    __ encode_utf8_from_utf16($src$$Register, $dst$$Register, $len$$Register,
+                              $result$$Register,
+                              $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
+                              $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
+                              $vtmp4$$FloatRegister, $vtmp5$$FloatRegister,
+                              $vtmp6$$FloatRegister, $vtmp7$$FloatRegister,
+                              $vtmp8$$FloatRegister, $vtmp9$$FloatRegister);
+  %}
+  ins_pipe(pipe_class_memory);
+%}
+
+// decode byte[] in UTF8 to char[] in UTF16
+instruct decode_utf8_to_utf16(iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len,
+                              vRegD_V0 vtmp0, vRegD_V1 vtmp1, vRegD_V2 vtmp2,
+                              vRegD_V3 vtmp3, vRegD_V4 vtmp4, vRegD_V5 vtmp5,
+                              vRegD_V6 vtmp6, vRegD_V7 vtmp7, vRegD_V12 vtmp8,
+                              vRegD_V13 vtmp9, vRegD vtmp10, iRegI_R0 result,
+                              rFlagsReg cr)
+%{
+  match(Set result (DecodeUtf8ToUtf16 src (Binary dst len)));
+  effect(USE_KILL src, USE_KILL dst, USE_KILL len, TEMP vtmp0, TEMP vtmp1,
+         TEMP vtmp2, TEMP vtmp3, TEMP vtmp4, TEMP vtmp5, TEMP vtmp6, TEMP vtmp7,
+         TEMP vtmp8, TEMP vtmp9, TEMP vtmp10, KILL cr);
+
+  format %{ "Decode UTF8 to UTF16 $src, $dst, $len -> $result # KILL $src $dst V0-V10 cr" %}
+  ins_encode %{
+    __ decode_utf8_to_utf16($src$$Register, $dst$$Register, $len$$Register,
+                            $result$$Register,
+                            $vtmp0$$FloatRegister, $vtmp1$$FloatRegister,
+                            $vtmp2$$FloatRegister, $vtmp3$$FloatRegister,
+                            $vtmp4$$FloatRegister, $vtmp5$$FloatRegister,
+                            $vtmp6$$FloatRegister, $vtmp7$$FloatRegister,
+                            $vtmp8$$FloatRegister, $vtmp9$$FloatRegister,
+                            $vtmp10$$FloatRegister);
+  %}
+  ins_pipe(pipe_class_memory);
+%}
+
 // ============================================================================
 // This name is KNOWN by the ADLC and cannot be changed.
 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
index 7b2f30132..a8a670023 100644
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
@@ -124,6 +124,8 @@ define_pd_global(intx, InlineSmallCode,          1000);
           range(1, 99)                                                  \
   product(ccstr, UseBranchProtection, "none",                           \
           "Branch Protection to use: none, standard, pac-ret")          \
+  product(bool, UseUTFConversionIntrinsics, false,                      \
+          "Use Intrinsics for conversion between UTF8 and UTF16")       \
   product(size_t, DynamicMaxHeapSizeLimit, ScaleForWordSize(96*M),      \
           "The limit of Dynamic maximum heap size (in bytes)")          \
   product(uintx, DynamicMaxHeapShrinkMinFreeRatio, 40,                  \
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index c1fe2b6e0..9552fca87 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -6550,6 +6550,678 @@ void MacroAssembler::encode_iso_array(Register src, Register dst,
   subw(res, len, cnt);
 }
 
+void MacroAssembler::decode_utf8_to_utf16(Register src, Register dst,
+                                          Register len, Register res,
+                                          FloatRegister vtmp0, FloatRegister vtmp1,
+                                          FloatRegister vtmp2, FloatRegister vtmp3,
+                                          FloatRegister vtmp4, FloatRegister vtmp5,
+                                          FloatRegister vtmp6, FloatRegister vtmp7,
+                                          FloatRegister vtmp8, FloatRegister vtmp9,
+                                          FloatRegister vtmp10) {
+  RegSet saved_regs = RegSet::range(r10, r16);
+  push(saved_regs, sp);
+
+  Register maxSrc = r10;
+  Register maxPos = r15; // order of registers can not be changed !!!
+  Register rTemp = rscratch1;
+  Register cMask = r11;
+  Register cnvTemp = r12;
+  Register maxStaPos = r13;
+  Register lookAddr = r14;
+  Register idx = rscratch2;
+  Register errInfo = r16;
+
+  FloatRegister vIn0 = vtmp0;
+  FloatRegister vCalcJohn = vtmp1;
+  FloatRegister vIn1 = vtmp2;
+  FloatRegister vIn2 = vtmp3;
+  FloatRegister vIn3 = vtmp4;
+  FloatRegister vCalcJack = vtmp5;
+  FloatRegister vCalcSuzie = vtmp6;
+
+  FloatRegister vCalcMartha = vtmp7;
+  FloatRegister vCalcGreg = vtmp8;
+  FloatRegister vCalcViki = vtmp9;
+  FloatRegister vErrors = vtmp10;
+
+  prfm(Address(src), PLDL1STRM);
+  Label LOOP_64, ST_SCALAR, DONE, ERROR_OCCURED, SUBR_CHECK_UTF8_BYTS;
+
+  mov(errInfo, 0);
+  movi(vErrors, T16B, 0);
+  movw(res, (unsigned)0);
+  add(maxSrc, src, len);
+  cmpw(len, 65);
+  br(LT, ST_SCALAR);
+
+  {
+  // moving back by 8 characters as described here:
+  // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/generic/utf8_to_utf16/utf8_to_utf16.h#L133
+    Label LD_CNT_LOOP, LOOP_OUT;
+
+    Register margin = r15;
+    Register leadingByte = rscratch2;
+    Register in = rscratch1;
+    Register index = r11;
+    movw(leadingByte, (unsigned)0);
+    movw(margin, (Register) len);
+
+    BIND(LD_CNT_LOOP);
+      cbz(margin, LOOP_OUT);
+      cmpw(leadingByte, 7);
+      br(GT, LOOP_OUT);
+      subw(index, margin, 1);
+      ldrb(in, Address(src, index));
+      subw(margin, margin, 1);
+      sxtb(in, in);
+      cmnw(in, 0x40);
+      br(LT, LD_CNT_LOOP);
+      addw(leadingByte, leadingByte, 1);
+      b(LD_CNT_LOOP);
+    BIND(LOOP_OUT);
+  }
+
+  cmpw(maxPos, 65);
+  br(LT, ST_SCALAR);
+
+  sub(maxPos, maxPos, 65);
+  add(maxPos, src, maxPos);
+  BIND(LOOP_64);
+  {
+    Label HALF_ASCII, NON_ASCII, CMASK_OK, CONV_LOOP;
+    cmp(src, maxPos);
+    br(GT, ST_SCALAR);
+
+      ld1(vIn0, T16B, post(src, 16));
+
+      umov(rTemp, vIn0, D, 0);
+      andr(rTemp, rTemp, 0x8080808080808080);
+      cbnz(rTemp, NON_ASCII);
+      umov(rTemp, vIn0, D, 1); // to get here 1st part of vector must be ascii
+      andr(rTemp, rTemp, 0x8080808080808080);
+      cbnz(rTemp, HALF_ASCII);
+
+        movi(vCalcJohn, T16B, 0);
+        st2(vIn0, vCalcJohn, T16B, post(dst, 32)); // For ASCII chars just store in memory
+        // putting 0 after every data byte
+        addw(res, res, 16); // update number of chars converted
+
+      b(LOOP_64);
+
+      BIND(HALF_ASCII);
+
+        movi(vCalcJohn, T16B, 0);
+        st2(vIn0, vCalcJohn, T8B, post(dst, 16)); // For ASCII chars just store in memory
+        // putting 0 after every data byte
+        sub(src, src, 8);
+        addw(res, res, 8); // update number of chars converted
+
+      b(LOOP_64);
+
+      BIND(NON_ASCII);
+
+        ld1(vIn1, vIn2, vIn3, T16B, post(src, 48));
+
+        movi(vCalcViki, T16B, 0); // check if utf8 bytes are valid for all 4 chunks
+        mov(vCalcGreg, T16B, vIn0);
+        bl(SUBR_CHECK_UTF8_BYTS);
+
+        mov(vCalcViki, T16B, vIn0);
+        mov(vCalcGreg, T16B, vIn1);
+        bl(SUBR_CHECK_UTF8_BYTS);
+
+        mov(vCalcViki, T16B, vIn1);
+        mov(vCalcGreg, T16B, vIn2);
+        bl(SUBR_CHECK_UTF8_BYTS);
+
+        mov(vCalcViki, T16B, vIn2);
+        mov(vCalcGreg, T16B, vIn3);
+        bl(SUBR_CHECK_UTF8_BYTS);
+
+        // calculate continuation mask by compare with -64 (8bit 0xC0)
+        // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/generic/utf8_to_utf16/utf8_to_utf16.h#L170
+        movi(vCalcJohn, T16B, 0xC0);
+        cm(GT, vCalcSuzie, T16B, vCalcJohn, vIn0);
+        cm(GT, vCalcJack, T16B, vCalcJohn, vIn1);
+        cm(GT, vCalcMartha, T16B, vCalcJohn, vIn2);
+        cm(GT, vCalcGreg, T16B, vCalcJohn, vIn3);
+
+        mov(rTemp, 0x8040201008040201); // {0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x01, 0x02, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
+        fmovd(vCalcJohn, rTemp);
+        ins(vCalcJohn, D, vCalcJohn, 1, 0);
+
+        andr(vCalcSuzie, T16B, vCalcSuzie, vCalcJohn); // use vCalcJohn filled above to present bytes as bitmask
+        andr(vCalcJack, T16B, vCalcJack, vCalcJohn); // where bit=1 for byte>0 and bit=0 for byte=0
+        addpv(vCalcSuzie, T16B, vCalcSuzie, vCalcJack);
+
+        andr(vCalcMartha, T16B, vCalcMartha, vCalcJohn);
+        andr(vCalcGreg, T16B, vCalcGreg, vCalcJohn);
+        addpv(vCalcMartha, T16B, vCalcMartha, vCalcGreg);
+
+        addpv(vCalcSuzie, T16B, vCalcSuzie, vCalcMartha);
+        addpv(vCalcSuzie, T16B, vCalcSuzie, vCalcSuzie);
+
+        umov(cMask, vCalcSuzie, D, 0);
+
+        andr(rTemp, cMask, 1);
+        cbz(rTemp, CMASK_OK);
+
+        mov(errInfo, -1);
+        b(ERROR_OCCURED);
+
+        BIND(CMASK_OK);
+        mvn(cMask, cMask); // utf8_leading_mask
+        lsr(cMask, cMask, 1);
+
+        sub(src, src, 64);
+        add(maxStaPos, src, 52);
+        BIND(CONV_LOOP);
+          cmp(src, maxStaPos);
+          br(GE, LOOP_64);
+
+          RuntimeAddress conv_u8_u18 = RuntimeAddress(StubRoutines::aarch64::convert_masked_utf8_to_utf16());
+          assert(conv_u8_u18.target() != nullptr, "convert_masked_utf8_to_utf16 stub has not been generated");
+          address tpc1 = trampoline_call(conv_u8_u18);
+          if (tpc1 == nullptr) {
+            postcond(pc() == badAddress);
+            mov(errInfo, -2);
+            b(ERROR_OCCURED);
+          } // dst and res are updated in the stub using post, but "consumed" is in cnvTemp
+
+          mov(errInfo, cnvTemp);
+          sxtb(errInfo, errInfo);
+          cmpw(errInfo, 0);
+          br(Assembler::LT, ERROR_OCCURED);
+
+          // add(actPos,actPos,cnvTemp);
+          add(src, src, cnvTemp);
+          lsrv(cMask, cMask, cnvTemp);
+
+        b(CONV_LOOP);
+
+        b(DONE);
+
+    b(LOOP_64);
+
+  }
+
+  BIND(SUBR_CHECK_UTF8_BYTS);
+  // input is in vCalcGreg, prev_input is in vCalcViki, result put to vErrors
+
+    ext(vCalcSuzie, T16B, vCalcViki, vCalcGreg, 15);
+    // checking special cases
+    // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/generic/utf8_to_utf16/utf8_to_utf16.h#L8
+    ushr(vCalcMartha, T16B, vCalcSuzie, 4);
+    mov(rTemp, 0x0202020202020202); // 8xTOO_LONG
+    fmovd(vCalcJohn, rTemp);
+    mov(rTemp, 0x4915012180808080); // 4xTWO_CONTS, TOO_SHORT | OVERLONG_2, etc...
+    fmovd(vCalcJack, rTemp);
+    ins(vCalcJohn, D, vCalcJack, 1, 0);
+    tbl(vCalcJohn, T16B, vCalcJohn, 1, vCalcMartha); // now vCalcJohn is byte_1_high
+
+    mov(rTemp, 0xCBCBCB8B8383A3E7); // CARRY | OVERLONG_3 | OVERLONG_2 | OVERLONG_4 etc...
+    fmovd(vCalcJack, rTemp);
+    mov(rTemp, 0xCBCBDBCBCBCBCBCB);
+    fmovd(vCalcMartha, rTemp);
+    ins(vCalcJack, D, vCalcMartha, 1, 0);
+
+    movi(vCalcMartha, T16B, 0x0F);
+    andr(vCalcMartha, T16B, vCalcSuzie, vCalcMartha);
+    tbl(vCalcJack, T16B, vCalcJack, 1, vCalcMartha); // now vCalcJack is byte_1_low
+
+    andr(vCalcJohn, T16B, vCalcJohn, vCalcJack);
+
+    mov(rTemp, 0x0101010101010101); // TOO_SHORT, TOO_SHORT etc...
+    fmovd(vCalcJack, rTemp);
+    mov(rTemp, 0x01010101BABAAEE6);
+    fmovd(vCalcMartha, rTemp);
+    ins(vCalcJack, D, vCalcMartha, 1, 0);
+    ushr(vCalcMartha, T16B, vCalcGreg, 4);
+    tbl(vCalcJack, T16B, vCalcJack, 1, vCalcMartha); // byte_2_high in vCalcJack
+
+    andr(vCalcJohn, T16B, vCalcJohn, vCalcJack); // result in vCalcJohn
+
+    // checking multibyte lengths
+    // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/generic/utf8_to_utf16/utf8_to_utf16.h#L99
+    ext(vCalcSuzie, T16B, vCalcViki, vCalcGreg, 14);
+    ext(vCalcMartha, T16B, vCalcViki, vCalcGreg, 13);
+
+    movi(vCalcJack, T16B, 0b11100000);
+    cm(HS, vCalcSuzie, T16B, vCalcSuzie, vCalcJack);
+
+    movi(vCalcJack, T16B, 0b11110000);
+    cm(HS, vCalcMartha, T16B, vCalcMartha, vCalcJack);
+
+    eor(vCalcSuzie, T16B, vCalcSuzie, vCalcMartha);
+
+    movi(vCalcJack, T16B, 0x80);
+    andr(vCalcSuzie, T16B, vCalcSuzie, vCalcJack);
+    eor(vCalcSuzie, T16B, vCalcSuzie, vCalcJohn);
+    orr(vErrors, T16B, vErrors, vCalcSuzie); // mark in vErrors when special cases not qeual to multibyte length
+    // END OF CHECK UTF8 BYTES
+
+  ret(lr);
+
+  BIND(ST_SCALAR);
+
+  mov(errInfo, -4); // return -4 when error in vErrors is noted
+  umaxv(vErrors, T16B, vErrors);
+  umov(rTemp, vErrors, B, 0);
+  cbnz(rTemp, ERROR_OCCURED);
+  mov(errInfo, 0);
+
+  {
+    RuntimeAddress conv_u8_u18 = RuntimeAddress(StubRoutines::aarch64::scalar_convert_utf8_to_utf16());
+    assert(conv_u8_u18.target() != nullptr, "scalar_convert_utf8_to_utf16 stub has not been generated");
+    address tpc1 = trampoline_call(conv_u8_u18);
+    if (tpc1 == nullptr) {
+      postcond(pc() == badAddress);
+      mov(errInfo, -6);
+      b(ERROR_OCCURED);
+    }
+
+    cbz(errInfo, DONE);
+  }
+
+  BIND(ERROR_OCCURED);
+  sxtb(errInfo, errInfo);
+  mov(res, errInfo);
+
+  BIND(DONE);
+  pop(saved_regs, sp);
+
+}
+
+// Clobbers: src, dst, res, rscratch1, rscratch2, rflags
+void MacroAssembler::encode_utf8_from_utf16(Register src, Register dst,
+                                            Register len, Register res,
+                                            FloatRegister vtmp0, FloatRegister vtmp1,
+                                            FloatRegister vtmp2, FloatRegister vtmp3,
+                                            FloatRegister vtmp4, FloatRegister vtmp5,
+                                            FloatRegister vtmp6, FloatRegister vtmp7,
+                                            FloatRegister vtmp8, FloatRegister vtmp9) {
+  RegSet saved_regs = RegSet::range(r10, r15);
+  push(saved_regs, sp);
+
+  Register max = rscratch1;
+  Register chk = rscratch2;
+  Register mask0 = r10;
+  Register mask1 = r11;
+  Register row0 = r12;
+  Register row1 = r13;
+  Register lookAddr = r14;
+  Register staSrcLen = r15;
+
+  FloatRegister vIn = vtmp0;
+  FloatRegister vCalcJohn = vtmp1;
+  FloatRegister vCalcSuzie = vtmp2;
+  FloatRegister vCalcBob = vtmp3;
+  FloatRegister vCalcMartha = vtmp4;
+  FloatRegister vCalcStanley = vtmp5;
+  FloatRegister vCalcViki = vtmp6;
+  FloatRegister vCalcJack = vtmp7;
+  FloatRegister vDupEven = vtmp8;
+  FloatRegister v3BShuffle = vtmp9;
+
+  uint64_t offset;
+
+  prfm(Address(src), PLDL1STRM);
+  Label LOOP_8, DONE, LOOP_8_TAIL, done_pop;
+
+  mov(staSrcLen, len);
+  movw(res, (unsigned)0);
+  cmpw(len, 8);
+  br(LT, LOOP_8_TAIL);
+
+  // fill helper registers to avoid multiple loads in converting loop
+  // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/arm64/arm_convert_utf16_to_utf8.cpp#L156
+  mov(chk, 0x0606040402020000);
+  fmovd(vDupEven, chk);
+  mov(chk, 0x0e0e0c0c0a0a0808);
+  fmovd(vCalcSuzie, chk);
+  ins(vDupEven, D, vCalcSuzie, 1, 0);
+
+  // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/arm64/arm_convert_utf16_to_utf8.cpp#L237
+  mov(chk, 0x0B0A050706010302);
+  fmovd(v3BShuffle, chk);
+  mov(chk, 0x000000000D0F0E09);
+  fmovd(vCalcSuzie, chk);
+  ins(v3BShuffle, D, vCalcSuzie, 1, 0);
+
+  BIND(LOOP_8);
+  {
+    Label LOOP_8_7FF, LOOP_8_GT7F, LOOP_8_GT7FF, NO_CHINA_FAST, LOOP_8_SCALAR;
+    cmpw(len, 8);
+    br(LT, LOOP_8_TAIL);
+    ld1(vIn, T8H, post(src, 16));
+    umaxv(vCalcSuzie, T8H, vIn);
+    umov(max, vCalcSuzie, H, 0);
+
+    cmpw(max, 0x7F);
+    br(Assembler::GT, LOOP_8_7FF);
+    // path for ascii characters only
+    xtn(vCalcSuzie, T8B, vIn, T8H); // take lower of each 16 bit element
+    st1(vCalcSuzie, T8B, Address(post(dst, 8))); // store in memory
+    subw(len, len, 8);
+    addw(res, res, 8);
+    b(LOOP_8);
+
+    BIND(LOOP_8_7FF);
+    cmpw(max, 0x7FF);
+    br(Assembler::GT, LOOP_8_GT7FF);
+    // path for 1 and 2 byte characters (utf-8 0x110xxxxx 0x10xxxxxx)
+    // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/arm64/arm_convert_utf16_to_utf8.cpp#L101
+    // prepare 2 bytes
+    movi(vCalcJohn, T8H, 0x1f, 8);
+    movi(vCalcBob, T8H, 0x3F);
+
+    shl(vCalcSuzie, T8H, vIn, 2);
+
+    andr(vCalcJohn, T16B, vCalcSuzie, vCalcJohn);
+    andr(vCalcBob, T16B, vIn, vCalcBob);
+
+    orr(vCalcJohn, T16B, vCalcJohn, vCalcBob);
+
+    mov(chk, 0xc080);
+    dup(vCalcSuzie, T8H, chk);
+    orr(vCalcBob, T16B, vCalcJohn, vCalcSuzie);
+
+    // find 1 bytes and merge with 2 bytes
+    movi(vCalcSuzie, T8H, 0x7F); // 0x007F
+
+    cm(HS, vCalcMartha, T8H, vCalcSuzie, vIn); // one_byte_bytemask (ASCII)
+
+    bit(vCalcBob, T16B, vIn, vCalcMartha);
+
+    // bitmask preparation for 8 bit lookup
+    mov(chk, 0x0040001000040001);
+    fmovd(vCalcJohn, chk);
+    mov(chk, 0x0080002000080002);
+    fmovd(vCalcSuzie, chk);
+    ins(vCalcJohn, D, vCalcSuzie, 1, 0);
+
+    andr(vCalcJohn, T16B, vCalcMartha, vCalcJohn);
+    addv(vCalcJohn, T8H, vCalcJohn);
+    umov(mask0, vCalcJohn, H, 0);
+
+    uint64_t offset;
+    adrp(lookAddr, ExternalAddress(StubRoutines::aarch64::pack_1_2_utf8_bytes_adr()), offset);
+    add(lookAddr, lookAddr, offset);
+    // calculate address
+    mov(chk, 17);
+    mul(row0, mask0, chk);
+    add(row0, lookAddr, row0);
+    add(row0, row0, 1);
+    // load from pack_1_2_utf8_bytes lookup table
+    ld1(vCalcMartha, T8H, row0);
+    tbl(vCalcBob, T16B, vCalcBob, 1, vCalcMartha); // perform lookup
+
+    sub(row0, row0, 1);
+    ldrb(row0, row0);
+
+    st1(vCalcBob, T16B, Address(post(dst, row0)));
+
+    subw(len, len, 8);
+    addw(res, res, row0);
+
+    b(LOOP_8); // continue
+
+    BIND(LOOP_8_GT7FF);
+
+    // check for existence 4 byte code units
+    movi(vCalcSuzie, T8H, 0xF8, 8); // 0xf800
+    andr(vCalcSuzie, T16B, vCalcSuzie, vIn);
+
+    movi(vCalcJohn, T8H, 0xD8, 8); // 0xd800
+    cm(EQ, vCalcSuzie, T8H, vCalcSuzie, vCalcJohn);
+    umaxv(vCalcSuzie, T8H, vCalcSuzie);
+    umov(chk, vCalcSuzie, H, 0);
+
+    cbnz(chk, LOOP_8_SCALAR); // if there are 4 bytes go to scalar solution
+    // https://github.com/simdutf/simdutf/blob/dfaaa29b9855b04127ad12171e719db04d048318/src/arm64/arm_convert_utf16_to_utf8.cpp#L151
+    // case: code units from register produce either 1, 2 or 3 UTF-8 bytes
+    tbl(vCalcJohn, T16B, vIn, 1, vDupEven);
+
+    mov(chk, 0b0011111101111111);
+    dup(vCalcSuzie, T8H, chk);
+    andr(vCalcJohn, T16B, vCalcJohn, vCalcSuzie);
+
+    movi(vCalcSuzie, T8H, 0x80, 8); // 0b1000000000000000
+    orr(vCalcJohn, T16B, vCalcJohn, vCalcSuzie);
+
+    ushr(vCalcBob, T8H, vIn, 12);
+
+    mov(chk, 0b0000111111000000);
+    dup(vCalcSuzie, T8H, chk);
+    andr(vCalcMartha, T16B, vIn, vCalcSuzie);
+
+    shl(vCalcMartha, T8H, vCalcMartha, 2);
+
+    orr(vCalcBob, T16B, vCalcBob, vCalcMartha);
+
+    mov(chk, 0b1100000011100000);
+    dup(vCalcSuzie, T8H, chk);
+    orr(vCalcBob, T16B, vCalcBob, vCalcSuzie);
+
+    mvni(vCalcSuzie, T8H, 0xF8, 8); // 0x07FF
+
+    cm(HS, vCalcMartha, T8H, vCalcSuzie, vIn);
+
+    movi(vCalcSuzie, T8H, 0x40, 8); // 0b0100000000000000
+    bic(vCalcSuzie, T16B, vCalcSuzie, vCalcMartha);
+    eor(vCalcBob, T16B, vCalcBob, vCalcSuzie);
+
+    zip1(vCalcStanley, T8H, vCalcJohn, vCalcBob);
+    zip2(vCalcJohn, T8H, vCalcJohn, vCalcBob);
+
+    movi(vCalcSuzie, T8H, 0x7F);
+    cm(HS, vCalcBob, T8H, vCalcSuzie, vIn);
+
+    mov(chk, 0x0040001000040001);
+    fmovd(vCalcViki, chk);
+    mov(chk, 0x4000100004000100);
+    fmovd(vCalcSuzie, chk);
+    ins(vCalcViki, D, vCalcSuzie, 1, 0);
+
+    mov(chk, 0x0080002000080002);
+    fmovd(vCalcJack, chk);
+    mov(chk, 0x8000200008000200);
+    fmovd(vCalcSuzie, chk);
+    ins(vCalcJack, D, vCalcSuzie, 1, 0);
+
+    andr(vCalcBob, T16B, vCalcBob, vCalcViki);
+    andr(vCalcMartha, T16B, vCalcMartha, vCalcJack);
+    orr(vCalcBob, T16B, vCalcBob, vCalcMartha);
+
+    addv(vCalcBob, T8H, vCalcBob);
+    umov(mask0, vCalcBob, H, 0);
+
+    cbnz(mask0, NO_CHINA_FAST);
+
+    // We only have three-byte code units. Use fast path.
+    tbl(vCalcStanley, T16B, vCalcStanley, 1, v3BShuffle);
+    tbl(vCalcJohn, T16B, vCalcJohn, 1, v3BShuffle);
+
+    st1(vCalcStanley, T16B, dst);
+    add(dst, dst, 12);
+    st1(vCalcJohn, T16B, dst);
+    add(dst, dst, 12);
+
+    subw(len, len, 8);
+    addw(res, res, 24);
+    b(LOOP_8);
+
+    BIND(NO_CHINA_FAST);
+
+    lsr(mask1, mask0, 8);
+    andr(mask1, mask1, 0xff);
+    andr(mask0, mask0, 0xff);
+
+    adrp(lookAddr, ExternalAddress(StubRoutines::aarch64::pack_1_2_3_utf8_bytes_adr()), offset);
+    add(lookAddr, lookAddr, offset);
+
+    mov(chk, 17);
+    mul(row0, mask0, chk);
+    add(row0, lookAddr, row0);
+    mul(row1, mask1, chk);
+    add(row1, lookAddr, row1);
+    add(row0, row0, 1);
+    add(row1, row1, 1);
+
+    ld1(vCalcBob, T8H, row0);
+    ld1(vCalcMartha, T8H, row1);
+
+    tbl(vCalcStanley, T16B, vCalcStanley, 1, vCalcBob);
+    tbl(vCalcJohn, T16B, vCalcJohn, 1, vCalcMartha);
+
+    sub(row0, row0, 1);
+    sub(row1, row1, 1);
+    ldrb(row0, row0);
+    ldrb(row1, row1);
+
+    st1(vCalcStanley, T16B, Address(post(dst, row0)));
+    st1(vCalcJohn, T16B, Address(post(dst, row1)));
+
+    subw(len, len, 8);
+    addw(row0, row0, row1);
+    addw(res, res, row0);
+    b(LOOP_8);
+
+    BIND(LOOP_8_SCALAR);
+      sub(src, src, 16); // it was unable to convert using vector solution so get back to begining
+    BIND(LOOP_8_TAIL);
+    {
+    // rename for easy reading
+      Register in = chk;
+      Register iftmp = mask0;
+      Register tgtLen =mask1;
+      Register iftmp1 = row0;
+      Register iftmp2 = row1;
+
+      Label SCALAR_LOOP, CHK_2BYTES, CHK_3BYTES, SCALAR_SURROGATE_PAIR, SCALAR_SURROGATE_ERR, SCALAR_OUT;
+
+      cbz(len, DONE);
+
+      subw(tgtLen, len, 8);
+      cmpw(len, 8);
+      br(GT, SCALAR_LOOP);
+      movw(tgtLen, (unsigned)0);
+
+      BIND(SCALAR_LOOP);
+      cmpw(len, tgtLen);
+      br(LE, LOOP_8);
+
+      ldrh(in, post(src, 2));
+      subw(len, len, 1);
+      andw(iftmp, in, 0xFF80);
+      cbnz(iftmp, CHK_2BYTES);
+
+      strb(in, post(dst, 1)); // store 1 ascii character
+      addw(res, res, 1);
+      b(SCALAR_LOOP);
+
+      BIND(CHK_2BYTES);
+      andw(iftmp, in, 0xF800);
+      cbnz(iftmp, CHK_3BYTES);
+      lsr(iftmp, in, 6);
+      orr(iftmp, iftmp, 0b11000000);
+      andw(in, in, 0b111111);
+      orr(in, in, 0b10000000);
+      lsl(in, in, 8);
+      orr(iftmp, iftmp, in);
+
+      strh(iftmp, post(dst, 2));
+      addw(res, res, 2);
+      b(SCALAR_LOOP);
+
+      BIND(CHK_3BYTES);
+      andw(iftmp, in, 0xF800);
+      subw(iftmp, iftmp, 0xD800);
+      cbz(iftmp, SCALAR_SURROGATE_PAIR);
+      lsr(iftmp, in, 12);
+      orr(iftmp, iftmp, 0b11100000);
+      lsr(iftmp1, in, 6);
+      andw(iftmp1, iftmp1, 0b111111);
+      orr(iftmp1, iftmp1, 0b10000000);
+      lsl(iftmp1, iftmp1, 8);
+      orr(iftmp, iftmp, iftmp1);
+
+      strh(iftmp, post(dst, 2));
+      andw(in, in, 0b111111);
+      orr(in, in, 0b10000000);
+
+      strb(in, post(dst, 1));
+      addw(res, res, 3);
+      b(SCALAR_LOOP);
+
+      BIND(SCALAR_SURROGATE_PAIR);
+
+      cbz(len, SCALAR_SURROGATE_ERR);
+      ldrh(iftmp, post(src, 2));
+      subw(len, len, 1);
+      subw(in, in, 0xD800);
+      subw(iftmp, iftmp, 0xDC00);
+      orr(iftmp1, in, iftmp);
+      cmpw(iftmp1, 0x3FF);
+      br(Assembler::HI, SCALAR_SURROGATE_ERR);
+
+      lsl(in, in, 10);
+      addw(in, in, iftmp);
+      addw(in, in, 0x10000);
+
+      lsr(iftmp, in, 18);
+      orr(iftmp, iftmp, 0b11110000);
+
+      lsr(iftmp1, in, 12);
+      andw(iftmp1, iftmp1, 0b111111);
+      orr(iftmp1, iftmp1, 0b10000000);
+
+      lsr(iftmp2, in, 6);
+      andw(iftmp2, iftmp2, 0b111111);
+      orr(iftmp2, iftmp2, 0b10000000);
+
+      andw(in, in, 0b111111);
+      orr(in, in, 0b10000000);
+
+      lsl(iftmp1, iftmp1, 8);
+      lsl(iftmp2, iftmp2, 16);
+      lsl(in, in, 24);
+
+      orr(iftmp, iftmp, iftmp1);
+      orr(iftmp, iftmp, iftmp2);
+      orr(iftmp, iftmp, in);
+      strw(iftmp, post(dst, 4));
+      addw(res, res, 4);
+      b(SCALAR_LOOP);
+
+      BIND(SCALAR_SURROGATE_ERR);
+      sub(staSrcLen, staSrcLen, len);
+      negw(res, staSrcLen); // index of unmappable is returned as negative val
+      b(DONE);
+
+    b(DONE);
+    }
+
+  }
+
+  BIND(DONE);
+
+  // The Java caller interprets any positive return value as "fully encoded".
+  // If we ever get here with unconsumed UTF-16 code units left, force a
+  // negative return so the caller falls back to the scalar Java path instead
+  // of silently truncating the output.
+  cmpw(res, 0);
+  br(Assembler::LE, done_pop);
+  cbzw(len, done_pop);
+  subw(chk, staSrcLen, len);
+  negw(res, chk);
+
+  BIND(done_pop);
+
+  pop(saved_regs, sp);
+  // res is updated in the loops already
+}
+
 // Inflate byte[] array to char[].
 // Clobbers: src, dst, len, rflags, rscratch1, v0-v6
 address MacroAssembler::byte_array_inflate(Register src, Register dst, Register len,
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
index f9fa333fe..0b543180e 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
@@ -1563,6 +1563,23 @@ public:
                         FloatRegister vtmp2, FloatRegister vtmp3,
                         FloatRegister vtmp4, FloatRegister vtmp5);
 
+  void encode_utf8_from_utf16(Register src, Register dst,
+                              Register len, Register res,
+                              FloatRegister vtmp0, FloatRegister vtmp1,
+                              FloatRegister vtmp2, FloatRegister vtmp3,
+                              FloatRegister vtmp4, FloatRegister vtmp5,
+                              FloatRegister vtmp6, FloatRegister vtmp7,
+                              FloatRegister vtmp8, FloatRegister vtmp9);
+
+  void decode_utf8_to_utf16(Register src, Register dst,
+                            Register len, Register res,
+                            FloatRegister vtmp0, FloatRegister vtmp1,
+                            FloatRegister vtmp2, FloatRegister vtmp3,
+                            FloatRegister vtmp4, FloatRegister vtmp5,
+                            FloatRegister vtmp6, FloatRegister vtmp7,
+                            FloatRegister vtmp8, FloatRegister vtmp9,
+                            FloatRegister vtmp10);
+
   void generate_dsin_dcos(bool isCos, address npio2_hw, address two_over_pi,
       address pio2, address dsin_coef, address dcos_coef);
  private:
diff --git a/src/hotspot/cpu/aarch64/simdutf_utf_tables.hpp b/src/hotspot/cpu/aarch64/simdutf_utf_tables.hpp
new file mode 100644
index 000000000..8800716fd
--- /dev/null
+++ b/src/hotspot/cpu/aarch64/simdutf_utf_tables.hpp
@@ -0,0 +1,1602 @@
+/*
+ * 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_AARCH64_SIMDUTF_UTF_TABLES_HPP
+#define CPU_AARCH64_SIMDUTF_UTF_TABLES_HPP
+
+#ifndef STUB_ROUTINES_AARCH64_SIMDUTF_TABLES_IMPL
+#error "This header provides definitions and must only be included by stubRoutines_aarch64.cpp"
+#endif
+
+// UTF conversion lookup tables derived from simdutf (https://github.com/simdutf/simdutf).
+// See src/hotspot/share/legal/simdutf.md for licensing details.
+
+/**
+ * utf8bigindex uses about 8 kB
+ * shufutf8 uses about 3344 B
+ *
+ * So we use a bit over 11 kB. It would be
+ * easy to save about 4 kB by only
+ * storing the index in utf8bigindex, and
+ * deriving the consumed bytes otherwise.
+ * However, this may come at a significant (10% to 20%)
+ * performance penalty.
+ */
+
+ATTRIBUTE_ALIGNED(4096) jubyte StubRoutines::aarch64::_shufutf8[209][16] = {
+    {0, 255, 1, 255, 2, 255, 3, 255, 4, 255, 5, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 3, 255, 4, 255, 6, 5, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 3, 255, 5, 4, 6, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 3, 255, 5, 4, 7, 6, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 4, 3, 5, 255, 6, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 4, 3, 5, 255, 7, 6, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 4, 3, 6, 5, 7, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 2, 255, 4, 3, 6, 5, 8, 7, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 4, 255, 5, 255, 6, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 4, 255, 5, 255, 7, 6, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 4, 255, 6, 5, 7, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 4, 255, 6, 5, 8, 7, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 5, 4, 6, 255, 7, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 5, 4, 6, 255, 8, 7, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 5, 4, 7, 6, 8, 255, 0, 0, 0, 0},
+    {0, 255, 1, 255, 3, 2, 5, 4, 7, 6, 9, 8, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 4, 255, 5, 255, 6, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 4, 255, 5, 255, 7, 6, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 4, 255, 6, 5, 7, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 4, 255, 6, 5, 8, 7, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 5, 4, 6, 255, 7, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 5, 4, 6, 255, 8, 7, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 5, 4, 7, 6, 8, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 3, 255, 5, 4, 7, 6, 9, 8, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 5, 255, 6, 255, 7, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 5, 255, 6, 255, 8, 7, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 5, 255, 7, 6, 8, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 5, 255, 7, 6, 9, 8, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 6, 5, 7, 255, 8, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 6, 5, 7, 255, 9, 8, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 6, 5, 8, 7, 9, 255, 0, 0, 0, 0},
+    {0, 255, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 4, 255, 5, 255, 6, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 4, 255, 5, 255, 7, 6, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 4, 255, 6, 5, 7, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 4, 255, 6, 5, 8, 7, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 5, 4, 6, 255, 7, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 5, 4, 6, 255, 8, 7, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 5, 4, 7, 6, 8, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 3, 255, 5, 4, 7, 6, 9, 8, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 5, 255, 6, 255, 7, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 5, 255, 6, 255, 8, 7, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 5, 255, 7, 6, 8, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 5, 255, 7, 6, 9, 8, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 6, 5, 7, 255, 8, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 6, 5, 7, 255, 9, 8, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 6, 5, 8, 7, 9, 255, 0, 0, 0, 0},
+    {1, 0, 2, 255, 4, 3, 6, 5, 8, 7, 10, 9, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 5, 255, 6, 255, 7, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 5, 255, 6, 255, 8, 7, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 5, 255, 7, 6, 8, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 5, 255, 7, 6, 9, 8, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 6, 5, 7, 255, 8, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 6, 5, 7, 255, 9, 8, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 6, 5, 8, 7, 9, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 4, 255, 6, 5, 8, 7, 10, 9, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 6, 255, 7, 255, 8, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 6, 255, 7, 255, 9, 8, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 6, 255, 8, 7, 9, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 6, 255, 8, 7, 10, 9, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 7, 6, 8, 255, 9, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 7, 6, 8, 255, 10, 9, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 255, 0, 0, 0, 0},
+    {1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 0, 0, 0, 0},
+    {0, 255, 255, 255, 1, 255, 255, 255, 2, 255, 255, 255, 3, 255, 255, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 2, 255, 255, 255, 4, 3, 255, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 2, 255, 255, 255, 5, 4, 3, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 3, 2, 255, 255, 4, 255, 255, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 3, 2, 255, 255, 5, 4, 255, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 3, 2, 255, 255, 6, 5, 4, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 4, 3, 2, 255, 5, 255, 255, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 4, 3, 2, 255, 6, 5, 255, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 4, 3, 2, 255, 7, 6, 5, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 3, 255, 255, 255, 4, 255, 255, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 3, 255, 255, 255, 5, 4, 255, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 3, 255, 255, 255, 6, 5, 4, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 4, 3, 255, 255, 5, 255, 255, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 4, 3, 255, 255, 6, 5, 255, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 4, 3, 255, 255, 7, 6, 5, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 5, 4, 3, 255, 6, 255, 255, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 5, 4, 3, 255, 7, 6, 255, 255},
+    {0, 255, 255, 255, 2, 1, 255, 255, 5, 4, 3, 255, 8, 7, 6, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 4, 255, 255, 255, 5, 255, 255, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 4, 255, 255, 255, 6, 5, 255, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 4, 255, 255, 255, 7, 6, 5, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 5, 4, 255, 255, 6, 255, 255, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 5, 4, 255, 255, 7, 6, 255, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 5, 4, 255, 255, 8, 7, 6, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 6, 5, 4, 255, 7, 255, 255, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 6, 5, 4, 255, 8, 7, 255, 255},
+    {0, 255, 255, 255, 3, 2, 1, 255, 6, 5, 4, 255, 9, 8, 7, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 3, 255, 255, 255, 4, 255, 255, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 3, 255, 255, 255, 5, 4, 255, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 3, 255, 255, 255, 6, 5, 4, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 4, 3, 255, 255, 5, 255, 255, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 4, 3, 255, 255, 6, 5, 255, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 4, 3, 255, 255, 7, 6, 5, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 5, 4, 3, 255, 6, 255, 255, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 5, 4, 3, 255, 7, 6, 255, 255},
+    {1, 0, 255, 255, 2, 255, 255, 255, 5, 4, 3, 255, 8, 7, 6, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 4, 255, 255, 255, 5, 255, 255, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 4, 255, 255, 255, 6, 5, 255, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 4, 255, 255, 255, 7, 6, 5, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 5, 4, 255, 255, 6, 255, 255, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 5, 4, 255, 255, 7, 6, 255, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 5, 4, 255, 255, 8, 7, 6, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 6, 5, 4, 255, 7, 255, 255, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 6, 5, 4, 255, 8, 7, 255, 255},
+    {1, 0, 255, 255, 3, 2, 255, 255, 6, 5, 4, 255, 9, 8, 7, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 5, 255, 255, 255, 6, 255, 255, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 5, 255, 255, 255, 7, 6, 255, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 5, 255, 255, 255, 8, 7, 6, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 6, 5, 255, 255, 7, 255, 255, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 6, 5, 255, 255, 8, 7, 255, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 6, 5, 255, 255, 9, 8, 7, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 7, 6, 5, 255, 8, 255, 255, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 7, 6, 5, 255, 9, 8, 255, 255},
+    {1, 0, 255, 255, 4, 3, 2, 255, 7, 6, 5, 255, 10, 9, 8, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 4, 255, 255, 255, 5, 255, 255, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 4, 255, 255, 255, 6, 5, 255, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 4, 255, 255, 255, 7, 6, 5, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 5, 4, 255, 255, 6, 255, 255, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 5, 4, 255, 255, 7, 6, 255, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 5, 4, 255, 255, 8, 7, 6, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 6, 5, 4, 255, 7, 255, 255, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 6, 5, 4, 255, 8, 7, 255, 255},
+    {2, 1, 0, 255, 3, 255, 255, 255, 6, 5, 4, 255, 9, 8, 7, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 5, 255, 255, 255, 6, 255, 255, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 5, 255, 255, 255, 7, 6, 255, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 5, 255, 255, 255, 8, 7, 6, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 6, 5, 255, 255, 7, 255, 255, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 6, 5, 255, 255, 8, 7, 255, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 6, 5, 255, 255, 9, 8, 7, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 7, 6, 5, 255, 8, 255, 255, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 7, 6, 5, 255, 9, 8, 255, 255},
+    {2, 1, 0, 255, 4, 3, 255, 255, 7, 6, 5, 255, 10, 9, 8, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 6, 255, 255, 255, 7, 255, 255, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 6, 255, 255, 255, 8, 7, 255, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 6, 255, 255, 255, 9, 8, 7, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 7, 6, 255, 255, 8, 255, 255, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 7, 6, 255, 255, 9, 8, 255, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 7, 6, 255, 255, 10, 9, 8, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 8, 7, 6, 255, 9, 255, 255, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 8, 7, 6, 255, 10, 9, 255, 255},
+    {2, 1, 0, 255, 5, 4, 3, 255, 8, 7, 6, 255, 11, 10, 9, 255},
+    {0, 255, 255, 255, 1, 255, 255, 255, 2, 255, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 1, 255, 255, 255, 3, 2, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 1, 255, 255, 255, 4, 3, 2, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 1, 255, 255, 255, 5, 4, 3, 2, 0, 0, 0, 0},
+    {0, 255, 255, 255, 2, 1, 255, 255, 3, 255, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 2, 1, 255, 255, 4, 3, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 2, 1, 255, 255, 5, 4, 3, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 2, 1, 255, 255, 6, 5, 4, 3, 0, 0, 0, 0},
+    {0, 255, 255, 255, 3, 2, 1, 255, 4, 255, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 3, 2, 1, 255, 5, 4, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 3, 2, 1, 255, 6, 5, 4, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 3, 2, 1, 255, 7, 6, 5, 4, 0, 0, 0, 0},
+    {0, 255, 255, 255, 4, 3, 2, 1, 5, 255, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 4, 3, 2, 1, 6, 5, 255, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 4, 3, 2, 1, 7, 6, 5, 255, 0, 0, 0, 0},
+    {0, 255, 255, 255, 4, 3, 2, 1, 8, 7, 6, 5, 0, 0, 0, 0},
+    {1, 0, 255, 255, 2, 255, 255, 255, 3, 255, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 2, 255, 255, 255, 4, 3, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 2, 255, 255, 255, 5, 4, 3, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 2, 255, 255, 255, 6, 5, 4, 3, 0, 0, 0, 0},
+    {1, 0, 255, 255, 3, 2, 255, 255, 4, 255, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 3, 2, 255, 255, 5, 4, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 3, 2, 255, 255, 6, 5, 4, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 3, 2, 255, 255, 7, 6, 5, 4, 0, 0, 0, 0},
+    {1, 0, 255, 255, 4, 3, 2, 255, 5, 255, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 4, 3, 2, 255, 6, 5, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 4, 3, 2, 255, 7, 6, 5, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 4, 3, 2, 255, 8, 7, 6, 5, 0, 0, 0, 0},
+    {1, 0, 255, 255, 5, 4, 3, 2, 6, 255, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 5, 4, 3, 2, 7, 6, 255, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 5, 4, 3, 2, 8, 7, 6, 255, 0, 0, 0, 0},
+    {1, 0, 255, 255, 5, 4, 3, 2, 9, 8, 7, 6, 0, 0, 0, 0},
+    {2, 1, 0, 255, 3, 255, 255, 255, 4, 255, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 3, 255, 255, 255, 5, 4, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 3, 255, 255, 255, 6, 5, 4, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 3, 255, 255, 255, 7, 6, 5, 4, 0, 0, 0, 0},
+    {2, 1, 0, 255, 4, 3, 255, 255, 5, 255, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 4, 3, 255, 255, 6, 5, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 4, 3, 255, 255, 7, 6, 5, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 4, 3, 255, 255, 8, 7, 6, 5, 0, 0, 0, 0},
+    {2, 1, 0, 255, 5, 4, 3, 255, 6, 255, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 5, 4, 3, 255, 7, 6, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 5, 4, 3, 255, 8, 7, 6, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 5, 4, 3, 255, 9, 8, 7, 6, 0, 0, 0, 0},
+    {2, 1, 0, 255, 6, 5, 4, 3, 7, 255, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 6, 5, 4, 3, 8, 7, 255, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 6, 5, 4, 3, 9, 8, 7, 255, 0, 0, 0, 0},
+    {2, 1, 0, 255, 6, 5, 4, 3, 10, 9, 8, 7, 0, 0, 0, 0},
+    {3, 2, 1, 0, 4, 255, 255, 255, 5, 255, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 4, 255, 255, 255, 6, 5, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 4, 255, 255, 255, 7, 6, 5, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 4, 255, 255, 255, 8, 7, 6, 5, 0, 0, 0, 0},
+    {3, 2, 1, 0, 5, 4, 255, 255, 6, 255, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 5, 4, 255, 255, 7, 6, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 5, 4, 255, 255, 8, 7, 6, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 5, 4, 255, 255, 9, 8, 7, 6, 0, 0, 0, 0},
+    {3, 2, 1, 0, 6, 5, 4, 255, 7, 255, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 6, 5, 4, 255, 8, 7, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 6, 5, 4, 255, 9, 8, 7, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 6, 5, 4, 255, 10, 9, 8, 7, 0, 0, 0, 0},
+    {3, 2, 1, 0, 7, 6, 5, 4, 8, 255, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 7, 6, 5, 4, 9, 8, 255, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 7, 6, 5, 4, 10, 9, 8, 255, 0, 0, 0, 0},
+    {3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 0, 0, 0, 0}};
+
+/* number of two bytes : 64 */
+/* number of two + three bytes : 145 */
+/* number of two + three + four bytes : 209 */
+ATTRIBUTE_ALIGNED(4096) jubyte StubRoutines::aarch64::_utf8bigindex[4096][2] = {
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},
+    {161, 4},  {64, 4},   {209, 12}, {209, 12}, {209, 12}, {147, 5},  {209, 12},
+    {150, 5},  {162, 5},  {65, 5},   {209, 12}, {153, 5},  {165, 5},  {67, 5},
+    {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {209, 12},
+    {148, 6},  {209, 12}, {151, 6},  {163, 6},  {66, 6},   {209, 12}, {154, 6},
+    {166, 6},  {68, 6},   {178, 6},  {74, 6},   {92, 6},   {64, 4},   {209, 12},
+    {157, 6},  {169, 6},  {70, 6},   {181, 6},  {76, 6},   {94, 6},   {65, 5},
+    {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {152, 7},
+    {164, 7},  {145, 3},  {209, 12}, {155, 7},  {167, 7},  {69, 7},   {179, 7},
+    {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {170, 7},  {71, 7},
+    {182, 7},  {77, 7},   {95, 7},   {65, 5},   {194, 7},  {83, 7},   {101, 7},
+    {67, 5},   {119, 7},  {73, 5},   {91, 5},   {1, 7},    {209, 12}, {209, 12},
+    {173, 7},  {148, 6},  {185, 7},  {79, 7},   {97, 7},   {66, 6},   {197, 7},
+    {85, 7},   {103, 7},  {68, 6},   {121, 7},  {74, 6},   {92, 6},   {2, 7},
+    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {76, 6},   {94, 6},
+    {4, 7},    {193, 6},  {82, 6},   {100, 6},  {8, 7},    {118, 6},  {16, 7},
+    {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {145, 3},  {209, 12}, {156, 8},  {168, 8},  {146, 4},
+    {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},  {171, 8},
+    {72, 8},   {183, 8},  {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},
+    {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12},
+    {209, 12}, {174, 8},  {148, 6},  {186, 8},  {80, 8},   {98, 8},   {66, 6},
+    {198, 8},  {86, 8},   {104, 8},  {68, 6},   {122, 8},  {74, 6},   {92, 6},
+    {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},  {76, 6},
+    {94, 6},   {5, 8},    {193, 6},  {82, 6},   {100, 6},  {9, 8},    {118, 6},
+    {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},
+    {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},
+    {112, 8},  {71, 7},   {130, 8},  {77, 7},   {95, 7},   {6, 8},    {194, 7},
+    {83, 7},   {101, 7},  {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},
+    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},
+    {66, 6},   {197, 7},  {85, 7},   {103, 7},  {12, 8},   {121, 7},  {20, 8},
+    {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},
+    {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},
+    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12},
+    {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12},
+    {160, 9},  {172, 9},  {147, 5},  {184, 9},  {150, 5},  {162, 5},  {65, 5},
+    {196, 9},  {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},
+    {64, 4},   {209, 12}, {209, 12}, {175, 9},  {148, 6},  {187, 9},  {81, 9},
+    {99, 9},   {66, 6},   {199, 9},  {87, 9},   {105, 9},  {68, 6},   {123, 9},
+    {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},  {111, 9},  {70, 6},
+    {129, 9},  {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},
+    {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {190, 9},  {152, 7},  {164, 7},  {145, 3},  {202, 9},
+    {89, 9},   {107, 9},  {69, 7},   {125, 9},  {75, 7},   {93, 7},   {64, 4},
+    {209, 12}, {158, 7},  {113, 9},  {71, 7},   {131, 9},  {77, 7},   {95, 7},
+    {7, 9},    {194, 7},  {83, 7},   {101, 7},  {11, 9},   {119, 7},  {19, 9},
+    {35, 9},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {137, 9},
+    {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {103, 7},  {13, 9},
+    {121, 7},  {21, 9},   {37, 9},   {2, 7},    {209, 12}, {157, 6},  {109, 7},
+    {70, 6},   {127, 7},  {25, 9},   {41, 9},   {4, 7},    {193, 6},  {82, 6},
+    {49, 9},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},
+    {205, 9},  {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},
+    {64, 4},   {209, 12}, {159, 8},  {115, 9},  {72, 8},   {133, 9},  {78, 8},
+    {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},
+    {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},
+    {139, 9},  {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},   {104, 8},
+    {14, 9},   {122, 8},  {22, 9},   {38, 9},   {3, 8},    {209, 12}, {157, 6},
+    {110, 8},  {70, 6},   {128, 8},  {26, 9},   {42, 9},   {5, 8},    {193, 6},
+    {82, 6},   {50, 9},   {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},
+    {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},
+    {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},
+    {28, 9},   {44, 9},   {6, 8},    {194, 7},  {83, 7},   {52, 9},   {10, 8},
+    {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},
+    {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},
+    {56, 9},   {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12},
+    {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},
+    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12},
+    {149, 4},  {161, 4},  {64, 4},   {209, 12}, {209, 12}, {209, 12}, {147, 5},
+    {209, 12}, {150, 5},  {162, 5},  {65, 5},   {209, 12}, {153, 5},  {165, 5},
+    {67, 5},   {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12},
+    {176, 10}, {148, 6},  {188, 10}, {151, 6},  {163, 6},  {66, 6},   {200, 10},
+    {154, 6},  {166, 6},  {68, 6},   {178, 6},  {74, 6},   {92, 6},   {64, 4},
+    {209, 12}, {157, 6},  {169, 6},  {70, 6},   {181, 6},  {76, 6},   {94, 6},
+    {65, 5},   {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},
+    {91, 5},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {191, 10},
+    {152, 7},  {164, 7},  {145, 3},  {203, 10}, {90, 10},  {108, 10}, {69, 7},
+    {126, 10}, {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {114, 10},
+    {71, 7},   {132, 10}, {77, 7},   {95, 7},   {65, 5},   {194, 7},  {83, 7},
+    {101, 7},  {67, 5},   {119, 7},  {73, 5},   {91, 5},   {1, 7},    {209, 12},
+    {209, 12}, {173, 7},  {148, 6},  {138, 10}, {79, 7},   {97, 7},   {66, 6},
+    {197, 7},  {85, 7},   {103, 7},  {68, 6},   {121, 7},  {74, 6},   {92, 6},
+    {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {76, 6},
+    {94, 6},   {4, 7},    {193, 6},  {82, 6},   {100, 6},  {8, 7},    {118, 6},
+    {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {145, 3},  {206, 10}, {156, 8},  {168, 8},
+    {146, 4},  {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},
+    {116, 10}, {72, 8},   {134, 10}, {78, 8},   {96, 8},   {65, 5},   {195, 8},
+    {84, 8},   {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},
+    {209, 12}, {209, 12}, {174, 8},  {148, 6},  {140, 10}, {80, 8},   {98, 8},
+    {66, 6},   {198, 8},  {86, 8},   {104, 8},  {15, 10},  {122, 8},  {23, 10},
+    {39, 10},  {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},
+    {27, 10},  {43, 10},  {5, 8},    {193, 6},  {82, 6},   {51, 10},  {9, 8},
+    {118, 6},  {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},
+    {106, 8},  {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12},
+    {158, 7},  {112, 8},  {71, 7},   {130, 8},  {29, 10},  {45, 10},  {6, 8},
+    {194, 7},  {83, 7},   {53, 10},  {10, 8},   {119, 7},  {18, 8},   {34, 8},
+    {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},
+    {97, 7},   {66, 6},   {197, 7},  {85, 7},   {57, 10},  {12, 8},   {121, 7},
+    {20, 8},   {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},
+    {127, 7},  {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},
+    {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12},
+    {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},
+    {209, 12}, {160, 9},  {172, 9},  {147, 5},  {184, 9},  {150, 5},  {162, 5},
+    {65, 5},   {196, 9},  {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},
+    {91, 5},   {64, 4},   {209, 12}, {209, 12}, {175, 9},  {148, 6},  {142, 10},
+    {81, 9},   {99, 9},   {66, 6},   {199, 9},  {87, 9},   {105, 9},  {68, 6},
+    {123, 9},  {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},  {111, 9},
+    {70, 6},   {129, 9},  {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},
+    {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {190, 9},  {152, 7},  {164, 7},  {145, 3},
+    {202, 9},  {89, 9},   {107, 9},  {69, 7},   {125, 9},  {75, 7},   {93, 7},
+    {64, 4},   {209, 12}, {158, 7},  {113, 9},  {71, 7},   {131, 9},  {30, 10},
+    {46, 10},  {7, 9},    {194, 7},  {83, 7},   {54, 10},  {11, 9},   {119, 7},
+    {19, 9},   {35, 9},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},
+    {137, 9},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {58, 10},
+    {13, 9},   {121, 7},  {21, 9},   {37, 9},   {2, 7},    {209, 12}, {157, 6},
+    {109, 7},  {70, 6},   {127, 7},  {25, 9},   {41, 9},   {4, 7},    {193, 6},
+    {82, 6},   {49, 9},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {145, 3},  {205, 9},  {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},
+    {161, 4},  {64, 4},   {209, 12}, {159, 8},  {115, 9},  {72, 8},   {133, 9},
+    {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},
+    {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},
+    {148, 6},  {139, 9},  {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},
+    {60, 10},  {14, 9},   {122, 8},  {22, 9},   {38, 9},   {3, 8},    {209, 12},
+    {157, 6},  {110, 8},  {70, 6},   {128, 8},  {26, 9},   {42, 9},   {5, 8},
+    {193, 6},  {82, 6},   {50, 9},   {9, 8},    {118, 6},  {17, 8},   {33, 8},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},
+    {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},
+    {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},
+    {130, 8},  {28, 9},   {44, 9},   {6, 8},    {194, 7},  {83, 7},   {52, 9},
+    {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12},
+    {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},
+    {85, 7},   {56, 9},   {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},
+    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},
+    {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},
+    {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},
+    {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12}, {209, 12}, {209, 12},
+    {147, 5},  {209, 12}, {150, 5},  {162, 5},  {65, 5},   {209, 12}, {153, 5},
+    {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12},
+    {209, 12}, {209, 12}, {148, 6},  {209, 12}, {151, 6},  {163, 6},  {66, 6},
+    {209, 12}, {154, 6},  {166, 6},  {68, 6},   {178, 6},  {74, 6},   {92, 6},
+    {64, 4},   {209, 12}, {157, 6},  {169, 6},  {70, 6},   {181, 6},  {76, 6},
+    {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},
+    {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {192, 11}, {152, 7},  {164, 7},  {145, 3},  {204, 11}, {155, 7},  {167, 7},
+    {69, 7},   {179, 7},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},
+    {170, 7},  {71, 7},   {182, 7},  {77, 7},   {95, 7},   {65, 5},   {194, 7},
+    {83, 7},   {101, 7},  {67, 5},   {119, 7},  {73, 5},   {91, 5},   {1, 7},
+    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {185, 7},  {79, 7},   {97, 7},
+    {66, 6},   {197, 7},  {85, 7},   {103, 7},  {68, 6},   {121, 7},  {74, 6},
+    {92, 6},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},
+    {76, 6},   {94, 6},   {4, 7},    {193, 6},  {82, 6},   {100, 6},  {8, 7},
+    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {207, 11}, {156, 8},
+    {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12},
+    {159, 8},  {117, 11}, {72, 8},   {135, 11}, {78, 8},   {96, 8},   {65, 5},
+    {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},
+    {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},  {141, 11}, {80, 8},
+    {98, 8},   {66, 6},   {198, 8},  {86, 8},   {104, 8},  {68, 6},   {122, 8},
+    {74, 6},   {92, 6},   {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},
+    {128, 8},  {76, 6},   {94, 6},   {5, 8},    {193, 6},  {82, 6},   {100, 6},
+    {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},
+    {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},
+    {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},  {77, 7},   {95, 7},
+    {6, 8},    {194, 7},  {83, 7},   {101, 7},  {10, 8},   {119, 7},  {18, 8},
+    {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},
+    {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {103, 7},  {12, 8},
+    {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},
+    {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},
+    {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},
+    {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},
+    {64, 4},   {209, 12}, {160, 9},  {172, 9},  {147, 5},  {184, 9},  {150, 5},
+    {162, 5},  {65, 5},   {196, 9},  {153, 5},  {165, 5},  {67, 5},   {177, 5},
+    {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {175, 9},  {148, 6},
+    {143, 11}, {81, 9},   {99, 9},   {66, 6},   {199, 9},  {87, 9},   {105, 9},
+    {68, 6},   {123, 9},  {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},
+    {111, 9},  {70, 6},   {129, 9},  {76, 6},   {94, 6},   {65, 5},   {193, 6},
+    {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {190, 9},  {152, 7},  {164, 7},
+    {145, 3},  {202, 9},  {89, 9},   {107, 9},  {69, 7},   {125, 9},  {75, 7},
+    {93, 7},   {64, 4},   {209, 12}, {158, 7},  {113, 9},  {71, 7},   {131, 9},
+    {31, 11},  {47, 11},  {7, 9},    {194, 7},  {83, 7},   {55, 11},  {11, 9},
+    {119, 7},  {19, 9},   {35, 9},   {1, 7},    {209, 12}, {209, 12}, {173, 7},
+    {148, 6},  {137, 9},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},
+    {59, 11},  {13, 9},   {121, 7},  {21, 9},   {37, 9},   {2, 7},    {209, 12},
+    {157, 6},  {109, 7},  {70, 6},   {127, 7},  {25, 9},   {41, 9},   {4, 7},
+    {193, 6},  {82, 6},   {49, 9},   {8, 7},    {118, 6},  {16, 7},   {32, 7},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {145, 3},  {205, 9},  {156, 8},  {168, 8},  {146, 4},  {180, 8},
+    {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},  {115, 9},  {72, 8},
+    {133, 9},  {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},
+    {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12},
+    {174, 8},  {148, 6},  {139, 9},  {80, 8},   {98, 8},   {66, 6},   {198, 8},
+    {86, 8},   {61, 11},  {14, 9},   {122, 8},  {22, 9},   {38, 9},   {3, 8},
+    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},  {26, 9},   {42, 9},
+    {5, 8},    {193, 6},  {82, 6},   {50, 9},   {9, 8},    {118, 6},  {17, 8},
+    {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},
+    {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},
+    {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},
+    {71, 7},   {130, 8},  {28, 9},   {44, 9},   {6, 8},    {194, 7},  {83, 7},
+    {52, 9},   {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12},
+    {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},
+    {197, 7},  {85, 7},   {56, 9},   {12, 8},   {121, 7},  {20, 8},   {36, 8},
+    {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},
+    {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},
+    {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12}, {209, 12},
+    {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12}, {209, 12},
+    {209, 12}, {147, 5},  {209, 12}, {150, 5},  {162, 5},  {65, 5},   {209, 12},
+    {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},   {64, 4},
+    {209, 12}, {209, 12}, {176, 10}, {148, 6},  {188, 10}, {151, 6},  {163, 6},
+    {66, 6},   {200, 10}, {154, 6},  {166, 6},  {68, 6},   {178, 6},  {74, 6},
+    {92, 6},   {64, 4},   {209, 12}, {157, 6},  {169, 6},  {70, 6},   {181, 6},
+    {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},  {67, 5},
+    {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {191, 10}, {152, 7},  {164, 7},  {145, 3},  {203, 10}, {90, 10},
+    {108, 10}, {69, 7},   {126, 10}, {75, 7},   {93, 7},   {64, 4},   {209, 12},
+    {158, 7},  {114, 10}, {71, 7},   {132, 10}, {77, 7},   {95, 7},   {65, 5},
+    {194, 7},  {83, 7},   {101, 7},  {67, 5},   {119, 7},  {73, 5},   {91, 5},
+    {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {138, 10}, {79, 7},
+    {97, 7},   {66, 6},   {197, 7},  {85, 7},   {103, 7},  {68, 6},   {121, 7},
+    {74, 6},   {92, 6},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},
+    {127, 7},  {76, 6},   {94, 6},   {4, 7},    {193, 6},  {82, 6},   {100, 6},
+    {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {206, 10},
+    {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},  {64, 4},
+    {209, 12}, {159, 8},  {116, 10}, {72, 8},   {134, 10}, {78, 8},   {96, 8},
+    {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},  {73, 5},
+    {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},  {140, 10},
+    {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},   {62, 11},  {15, 10},
+    {122, 8},  {23, 10},  {39, 10},  {3, 8},    {209, 12}, {157, 6},  {110, 8},
+    {70, 6},   {128, 8},  {27, 10},  {43, 10},  {5, 8},    {193, 6},  {82, 6},
+    {51, 10},  {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},  {145, 3},
+    {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},   {93, 7},
+    {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},  {29, 10},
+    {45, 10},  {6, 8},    {194, 7},  {83, 7},   {53, 10},  {10, 8},   {119, 7},
+    {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},
+    {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {57, 10},
+    {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12}, {157, 6},
+    {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},    {193, 6},
+    {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},
+    {161, 4},  {64, 4},   {209, 12}, {160, 9},  {172, 9},  {147, 5},  {184, 9},
+    {150, 5},  {162, 5},  {65, 5},   {196, 9},  {153, 5},  {165, 5},  {67, 5},
+    {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {175, 9},
+    {148, 6},  {142, 10}, {81, 9},   {99, 9},   {66, 6},   {199, 9},  {87, 9},
+    {105, 9},  {68, 6},   {123, 9},  {74, 6},   {92, 6},   {64, 4},   {209, 12},
+    {157, 6},  {111, 9},  {70, 6},   {129, 9},  {76, 6},   {94, 6},   {65, 5},
+    {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {190, 9},  {152, 7},
+    {164, 7},  {145, 3},  {202, 9},  {89, 9},   {107, 9},  {69, 7},   {125, 9},
+    {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {113, 9},  {71, 7},
+    {131, 9},  {30, 10},  {46, 10},  {7, 9},    {194, 7},  {83, 7},   {54, 10},
+    {11, 9},   {119, 7},  {19, 9},   {35, 9},   {1, 7},    {209, 12}, {209, 12},
+    {173, 7},  {148, 6},  {137, 9},  {79, 7},   {97, 7},   {66, 6},   {197, 7},
+    {85, 7},   {58, 10},  {13, 9},   {121, 7},  {21, 9},   {37, 9},   {2, 7},
+    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {25, 9},   {41, 9},
+    {4, 7},    {193, 6},  {82, 6},   {49, 9},   {8, 7},    {118, 6},  {16, 7},
+    {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {145, 3},  {205, 9},  {156, 8},  {168, 8},  {146, 4},
+    {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},  {115, 9},
+    {72, 8},   {133, 9},  {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},
+    {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12},
+    {209, 12}, {174, 8},  {148, 6},  {139, 9},  {80, 8},   {98, 8},   {66, 6},
+    {198, 8},  {86, 8},   {60, 10},  {14, 9},   {122, 8},  {22, 9},   {38, 9},
+    {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},  {26, 9},
+    {42, 9},   {5, 8},    {193, 6},  {82, 6},   {50, 9},   {9, 8},    {118, 6},
+    {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},
+    {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},
+    {112, 8},  {71, 7},   {130, 8},  {28, 9},   {44, 9},   {6, 8},    {194, 7},
+    {83, 7},   {52, 9},   {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},
+    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},
+    {66, 6},   {197, 7},  {85, 7},   {56, 9},   {12, 8},   {121, 7},  {20, 8},
+    {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},
+    {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},
+    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12},
+    {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12},
+    {209, 12}, {209, 12}, {147, 5},  {209, 12}, {150, 5},  {162, 5},  {65, 5},
+    {209, 12}, {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},
+    {64, 4},   {209, 12}, {209, 12}, {209, 12}, {148, 6},  {209, 12}, {151, 6},
+    {163, 6},  {66, 6},   {209, 12}, {154, 6},  {166, 6},  {68, 6},   {178, 6},
+    {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},  {169, 6},  {70, 6},
+    {181, 6},  {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},
+    {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {152, 7},  {164, 7},  {145, 3},  {209, 12},
+    {155, 7},  {167, 7},  {69, 7},   {179, 7},  {75, 7},   {93, 7},   {64, 4},
+    {209, 12}, {158, 7},  {170, 7},  {71, 7},   {182, 7},  {77, 7},   {95, 7},
+    {65, 5},   {194, 7},  {83, 7},   {101, 7},  {67, 5},   {119, 7},  {73, 5},
+    {91, 5},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {185, 7},
+    {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {103, 7},  {68, 6},
+    {121, 7},  {74, 6},   {92, 6},   {2, 7},    {209, 12}, {157, 6},  {109, 7},
+    {70, 6},   {127, 7},  {76, 6},   {94, 6},   {4, 7},    {193, 6},  {82, 6},
+    {100, 6},  {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},
+    {208, 12}, {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},
+    {64, 4},   {209, 12}, {159, 8},  {171, 8},  {72, 8},   {183, 8},  {78, 8},
+    {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},
+    {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},
+    {186, 8},  {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},   {104, 8},
+    {68, 6},   {122, 8},  {74, 6},   {92, 6},   {3, 8},    {209, 12}, {157, 6},
+    {110, 8},  {70, 6},   {128, 8},  {76, 6},   {94, 6},   {5, 8},    {193, 6},
+    {82, 6},   {100, 6},  {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},
+    {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},
+    {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},
+    {77, 7},   {95, 7},   {6, 8},    {194, 7},  {83, 7},   {101, 7},  {10, 8},
+    {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},
+    {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},
+    {103, 7},  {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12},
+    {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},
+    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12},
+    {149, 4},  {161, 4},  {64, 4},   {209, 12}, {160, 9},  {172, 9},  {147, 5},
+    {184, 9},  {150, 5},  {162, 5},  {65, 5},   {196, 9},  {153, 5},  {165, 5},
+    {67, 5},   {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12},
+    {175, 9},  {148, 6},  {144, 12}, {81, 9},   {99, 9},   {66, 6},   {199, 9},
+    {87, 9},   {105, 9},  {68, 6},   {123, 9},  {74, 6},   {92, 6},   {64, 4},
+    {209, 12}, {157, 6},  {111, 9},  {70, 6},   {129, 9},  {76, 6},   {94, 6},
+    {65, 5},   {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},
+    {91, 5},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {190, 9},
+    {152, 7},  {164, 7},  {145, 3},  {202, 9},  {89, 9},   {107, 9},  {69, 7},
+    {125, 9},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {113, 9},
+    {71, 7},   {131, 9},  {77, 7},   {95, 7},   {7, 9},    {194, 7},  {83, 7},
+    {101, 7},  {11, 9},   {119, 7},  {19, 9},   {35, 9},   {1, 7},    {209, 12},
+    {209, 12}, {173, 7},  {148, 6},  {137, 9},  {79, 7},   {97, 7},   {66, 6},
+    {197, 7},  {85, 7},   {103, 7},  {13, 9},   {121, 7},  {21, 9},   {37, 9},
+    {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {25, 9},
+    {41, 9},   {4, 7},    {193, 6},  {82, 6},   {49, 9},   {8, 7},    {118, 6},
+    {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {145, 3},  {205, 9},  {156, 8},  {168, 8},
+    {146, 4},  {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},
+    {115, 9},  {72, 8},   {133, 9},  {78, 8},   {96, 8},   {65, 5},   {195, 8},
+    {84, 8},   {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},
+    {209, 12}, {209, 12}, {174, 8},  {148, 6},  {139, 9},  {80, 8},   {98, 8},
+    {66, 6},   {198, 8},  {86, 8},   {104, 8},  {14, 9},   {122, 8},  {22, 9},
+    {38, 9},   {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},
+    {26, 9},   {42, 9},   {5, 8},    {193, 6},  {82, 6},   {50, 9},   {9, 8},
+    {118, 6},  {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},
+    {106, 8},  {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12},
+    {158, 7},  {112, 8},  {71, 7},   {130, 8},  {28, 9},   {44, 9},   {6, 8},
+    {194, 7},  {83, 7},   {52, 9},   {10, 8},   {119, 7},  {18, 8},   {34, 8},
+    {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},
+    {97, 7},   {66, 6},   {197, 7},  {85, 7},   {56, 9},   {12, 8},   {121, 7},
+    {20, 8},   {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},
+    {127, 7},  {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},
+    {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12},
+    {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},
+    {209, 12}, {209, 12}, {209, 12}, {147, 5},  {209, 12}, {150, 5},  {162, 5},
+    {65, 5},   {209, 12}, {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},
+    {91, 5},   {64, 4},   {209, 12}, {209, 12}, {176, 10}, {148, 6},  {188, 10},
+    {151, 6},  {163, 6},  {66, 6},   {200, 10}, {154, 6},  {166, 6},  {68, 6},
+    {178, 6},  {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},  {169, 6},
+    {70, 6},   {181, 6},  {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},
+    {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {191, 10}, {152, 7},  {164, 7},  {145, 3},
+    {203, 10}, {90, 10},  {108, 10}, {69, 7},   {126, 10}, {75, 7},   {93, 7},
+    {64, 4},   {209, 12}, {158, 7},  {114, 10}, {71, 7},   {132, 10}, {77, 7},
+    {95, 7},   {65, 5},   {194, 7},  {83, 7},   {101, 7},  {67, 5},   {119, 7},
+    {73, 5},   {91, 5},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},
+    {138, 10}, {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {103, 7},
+    {68, 6},   {121, 7},  {74, 6},   {92, 6},   {2, 7},    {209, 12}, {157, 6},
+    {109, 7},  {70, 6},   {127, 7},  {76, 6},   {94, 6},   {4, 7},    {193, 6},
+    {82, 6},   {100, 6},  {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {145, 3},  {206, 10}, {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},
+    {161, 4},  {64, 4},   {209, 12}, {159, 8},  {116, 10}, {72, 8},   {134, 10},
+    {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},
+    {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},
+    {148, 6},  {140, 10}, {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},
+    {63, 12},  {15, 10},  {122, 8},  {23, 10},  {39, 10},  {3, 8},    {209, 12},
+    {157, 6},  {110, 8},  {70, 6},   {128, 8},  {27, 10},  {43, 10},  {5, 8},
+    {193, 6},  {82, 6},   {51, 10},  {9, 8},    {118, 6},  {17, 8},   {33, 8},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},
+    {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},
+    {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},
+    {130, 8},  {29, 10},  {45, 10},  {6, 8},    {194, 7},  {83, 7},   {53, 10},
+    {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12},
+    {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},
+    {85, 7},   {57, 10},  {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},
+    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},
+    {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},
+    {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},
+    {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12}, {160, 9},  {172, 9},
+    {147, 5},  {184, 9},  {150, 5},  {162, 5},  {65, 5},   {196, 9},  {153, 5},
+    {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12},
+    {209, 12}, {175, 9},  {148, 6},  {142, 10}, {81, 9},   {99, 9},   {66, 6},
+    {199, 9},  {87, 9},   {105, 9},  {68, 6},   {123, 9},  {74, 6},   {92, 6},
+    {64, 4},   {209, 12}, {157, 6},  {111, 9},  {70, 6},   {129, 9},  {76, 6},
+    {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},
+    {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {190, 9},  {152, 7},  {164, 7},  {145, 3},  {202, 9},  {89, 9},   {107, 9},
+    {69, 7},   {125, 9},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},
+    {113, 9},  {71, 7},   {131, 9},  {30, 10},  {46, 10},  {7, 9},    {194, 7},
+    {83, 7},   {54, 10},  {11, 9},   {119, 7},  {19, 9},   {35, 9},   {1, 7},
+    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {137, 9},  {79, 7},   {97, 7},
+    {66, 6},   {197, 7},  {85, 7},   {58, 10},  {13, 9},   {121, 7},  {21, 9},
+    {37, 9},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},
+    {25, 9},   {41, 9},   {4, 7},    {193, 6},  {82, 6},   {49, 9},   {8, 7},
+    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {205, 9},  {156, 8},
+    {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12},
+    {159, 8},  {115, 9},  {72, 8},   {133, 9},  {78, 8},   {96, 8},   {65, 5},
+    {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},
+    {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},  {139, 9},  {80, 8},
+    {98, 8},   {66, 6},   {198, 8},  {86, 8},   {60, 10},  {14, 9},   {122, 8},
+    {22, 9},   {38, 9},   {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},
+    {128, 8},  {26, 9},   {42, 9},   {5, 8},    {193, 6},  {82, 6},   {50, 9},
+    {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},
+    {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},
+    {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},  {28, 9},   {44, 9},
+    {6, 8},    {194, 7},  {83, 7},   {52, 9},   {10, 8},   {119, 7},  {18, 8},
+    {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},
+    {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {56, 9},   {12, 8},
+    {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},
+    {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},
+    {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},
+    {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},
+    {64, 4},   {209, 12}, {209, 12}, {209, 12}, {147, 5},  {209, 12}, {150, 5},
+    {162, 5},  {65, 5},   {209, 12}, {153, 5},  {165, 5},  {67, 5},   {177, 5},
+    {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {209, 12}, {148, 6},
+    {209, 12}, {151, 6},  {163, 6},  {66, 6},   {209, 12}, {154, 6},  {166, 6},
+    {68, 6},   {178, 6},  {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},
+    {169, 6},  {70, 6},   {181, 6},  {76, 6},   {94, 6},   {65, 5},   {193, 6},
+    {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {192, 11}, {152, 7},  {164, 7},
+    {145, 3},  {204, 11}, {155, 7},  {167, 7},  {69, 7},   {179, 7},  {75, 7},
+    {93, 7},   {64, 4},   {209, 12}, {158, 7},  {170, 7},  {71, 7},   {182, 7},
+    {77, 7},   {95, 7},   {65, 5},   {194, 7},  {83, 7},   {101, 7},  {67, 5},
+    {119, 7},  {73, 5},   {91, 5},   {1, 7},    {209, 12}, {209, 12}, {173, 7},
+    {148, 6},  {185, 7},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},
+    {103, 7},  {68, 6},   {121, 7},  {74, 6},   {92, 6},   {2, 7},    {209, 12},
+    {157, 6},  {109, 7},  {70, 6},   {127, 7},  {76, 6},   {94, 6},   {4, 7},
+    {193, 6},  {82, 6},   {100, 6},  {8, 7},    {118, 6},  {16, 7},   {32, 7},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {145, 3},  {207, 11}, {156, 8},  {168, 8},  {146, 4},  {180, 8},
+    {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},  {117, 11}, {72, 8},
+    {135, 11}, {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},
+    {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12},
+    {174, 8},  {148, 6},  {141, 11}, {80, 8},   {98, 8},   {66, 6},   {198, 8},
+    {86, 8},   {104, 8},  {68, 6},   {122, 8},  {74, 6},   {92, 6},   {3, 8},
+    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},  {76, 6},   {94, 6},
+    {5, 8},    {193, 6},  {82, 6},   {100, 6},  {9, 8},    {118, 6},  {17, 8},
+    {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},
+    {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},
+    {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},
+    {71, 7},   {130, 8},  {77, 7},   {95, 7},   {6, 8},    {194, 7},  {83, 7},
+    {101, 7},  {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12},
+    {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},
+    {197, 7},  {85, 7},   {103, 7},  {12, 8},   {121, 7},  {20, 8},   {36, 8},
+    {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},
+    {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},
+    {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12}, {209, 12},
+    {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12}, {160, 9},
+    {172, 9},  {147, 5},  {184, 9},  {150, 5},  {162, 5},  {65, 5},   {196, 9},
+    {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},   {64, 4},
+    {209, 12}, {209, 12}, {175, 9},  {148, 6},  {143, 11}, {81, 9},   {99, 9},
+    {66, 6},   {199, 9},  {87, 9},   {105, 9},  {68, 6},   {123, 9},  {74, 6},
+    {92, 6},   {64, 4},   {209, 12}, {157, 6},  {111, 9},  {70, 6},   {129, 9},
+    {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},  {67, 5},
+    {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {190, 9},  {152, 7},  {164, 7},  {145, 3},  {202, 9},  {89, 9},
+    {107, 9},  {69, 7},   {125, 9},  {75, 7},   {93, 7},   {64, 4},   {209, 12},
+    {158, 7},  {113, 9},  {71, 7},   {131, 9},  {31, 11},  {47, 11},  {7, 9},
+    {194, 7},  {83, 7},   {55, 11},  {11, 9},   {119, 7},  {19, 9},   {35, 9},
+    {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {137, 9},  {79, 7},
+    {97, 7},   {66, 6},   {197, 7},  {85, 7},   {59, 11},  {13, 9},   {121, 7},
+    {21, 9},   {37, 9},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},
+    {127, 7},  {25, 9},   {41, 9},   {4, 7},    {193, 6},  {82, 6},   {49, 9},
+    {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {205, 9},
+    {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},  {64, 4},
+    {209, 12}, {159, 8},  {115, 9},  {72, 8},   {133, 9},  {78, 8},   {96, 8},
+    {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},  {73, 5},
+    {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},  {139, 9},
+    {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},   {61, 11},  {14, 9},
+    {122, 8},  {22, 9},   {38, 9},   {3, 8},    {209, 12}, {157, 6},  {110, 8},
+    {70, 6},   {128, 8},  {26, 9},   {42, 9},   {5, 8},    {193, 6},  {82, 6},
+    {50, 9},   {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},  {145, 3},
+    {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},   {93, 7},
+    {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},  {28, 9},
+    {44, 9},   {6, 8},    {194, 7},  {83, 7},   {52, 9},   {10, 8},   {119, 7},
+    {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},
+    {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {56, 9},
+    {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12}, {157, 6},
+    {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},    {193, 6},
+    {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {145, 3},  {209, 12}, {209, 12}, {209, 12}, {146, 4},  {209, 12}, {149, 4},
+    {161, 4},  {64, 4},   {209, 12}, {209, 12}, {209, 12}, {147, 5},  {209, 12},
+    {150, 5},  {162, 5},  {65, 5},   {209, 12}, {153, 5},  {165, 5},  {67, 5},
+    {177, 5},  {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {176, 10},
+    {148, 6},  {188, 10}, {151, 6},  {163, 6},  {66, 6},   {200, 10}, {154, 6},
+    {166, 6},  {68, 6},   {178, 6},  {74, 6},   {92, 6},   {64, 4},   {209, 12},
+    {157, 6},  {169, 6},  {70, 6},   {181, 6},  {76, 6},   {94, 6},   {65, 5},
+    {193, 6},  {82, 6},   {100, 6},  {67, 5},   {118, 6},  {73, 5},   {91, 5},
+    {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {191, 10}, {152, 7},
+    {164, 7},  {145, 3},  {203, 10}, {90, 10},  {108, 10}, {69, 7},   {126, 10},
+    {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},  {114, 10}, {71, 7},
+    {132, 10}, {77, 7},   {95, 7},   {65, 5},   {194, 7},  {83, 7},   {101, 7},
+    {67, 5},   {119, 7},  {73, 5},   {91, 5},   {1, 7},    {209, 12}, {209, 12},
+    {173, 7},  {148, 6},  {138, 10}, {79, 7},   {97, 7},   {66, 6},   {197, 7},
+    {85, 7},   {103, 7},  {68, 6},   {121, 7},  {74, 6},   {92, 6},   {2, 7},
+    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},  {76, 6},   {94, 6},
+    {4, 7},    {193, 6},  {82, 6},   {100, 6},  {8, 7},    {118, 6},  {16, 7},
+    {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {145, 3},  {206, 10}, {156, 8},  {168, 8},  {146, 4},
+    {180, 8},  {149, 4},  {161, 4},  {64, 4},   {209, 12}, {159, 8},  {116, 10},
+    {72, 8},   {134, 10}, {78, 8},   {96, 8},   {65, 5},   {195, 8},  {84, 8},
+    {102, 8},  {67, 5},   {120, 8},  {73, 5},   {91, 5},   {64, 4},   {209, 12},
+    {209, 12}, {174, 8},  {148, 6},  {140, 10}, {80, 8},   {98, 8},   {66, 6},
+    {198, 8},  {86, 8},   {62, 11},  {15, 10},  {122, 8},  {23, 10},  {39, 10},
+    {3, 8},    {209, 12}, {157, 6},  {110, 8},  {70, 6},   {128, 8},  {27, 10},
+    {43, 10},  {5, 8},    {193, 6},  {82, 6},   {51, 10},  {9, 8},    {118, 6},
+    {17, 8},   {33, 8},   {0, 6},    {209, 12}, {209, 12}, {209, 12}, {209, 12},
+    {189, 8},  {152, 7},  {164, 7},  {145, 3},  {201, 8},  {88, 8},   {106, 8},
+    {69, 7},   {124, 8},  {75, 7},   {93, 7},   {64, 4},   {209, 12}, {158, 7},
+    {112, 8},  {71, 7},   {130, 8},  {29, 10},  {45, 10},  {6, 8},    {194, 7},
+    {83, 7},   {53, 10},  {10, 8},   {119, 7},  {18, 8},   {34, 8},   {1, 7},
+    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {136, 8},  {79, 7},   {97, 7},
+    {66, 6},   {197, 7},  {85, 7},   {57, 10},  {12, 8},   {121, 7},  {20, 8},
+    {36, 8},   {2, 7},    {209, 12}, {157, 6},  {109, 7},  {70, 6},   {127, 7},
+    {24, 8},   {40, 8},   {4, 7},    {193, 6},  {82, 6},   {48, 8},   {8, 7},
+    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12}, {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},  {209, 12}, {209, 12},
+    {209, 12}, {146, 4},  {209, 12}, {149, 4},  {161, 4},  {64, 4},   {209, 12},
+    {160, 9},  {172, 9},  {147, 5},  {184, 9},  {150, 5},  {162, 5},  {65, 5},
+    {196, 9},  {153, 5},  {165, 5},  {67, 5},   {177, 5},  {73, 5},   {91, 5},
+    {64, 4},   {209, 12}, {209, 12}, {175, 9},  {148, 6},  {142, 10}, {81, 9},
+    {99, 9},   {66, 6},   {199, 9},  {87, 9},   {105, 9},  {68, 6},   {123, 9},
+    {74, 6},   {92, 6},   {64, 4},   {209, 12}, {157, 6},  {111, 9},  {70, 6},
+    {129, 9},  {76, 6},   {94, 6},   {65, 5},   {193, 6},  {82, 6},   {100, 6},
+    {67, 5},   {118, 6},  {73, 5},   {91, 5},   {0, 6},    {209, 12}, {209, 12},
+    {209, 12}, {209, 12}, {190, 9},  {152, 7},  {164, 7},  {145, 3},  {202, 9},
+    {89, 9},   {107, 9},  {69, 7},   {125, 9},  {75, 7},   {93, 7},   {64, 4},
+    {209, 12}, {158, 7},  {113, 9},  {71, 7},   {131, 9},  {30, 10},  {46, 10},
+    {7, 9},    {194, 7},  {83, 7},   {54, 10},  {11, 9},   {119, 7},  {19, 9},
+    {35, 9},   {1, 7},    {209, 12}, {209, 12}, {173, 7},  {148, 6},  {137, 9},
+    {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},   {58, 10},  {13, 9},
+    {121, 7},  {21, 9},   {37, 9},   {2, 7},    {209, 12}, {157, 6},  {109, 7},
+    {70, 6},   {127, 7},  {25, 9},   {41, 9},   {4, 7},    {193, 6},  {82, 6},
+    {49, 9},   {8, 7},    {118, 6},  {16, 7},   {32, 7},   {0, 6},    {209, 12},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {209, 12}, {145, 3},
+    {205, 9},  {156, 8},  {168, 8},  {146, 4},  {180, 8},  {149, 4},  {161, 4},
+    {64, 4},   {209, 12}, {159, 8},  {115, 9},  {72, 8},   {133, 9},  {78, 8},
+    {96, 8},   {65, 5},   {195, 8},  {84, 8},   {102, 8},  {67, 5},   {120, 8},
+    {73, 5},   {91, 5},   {64, 4},   {209, 12}, {209, 12}, {174, 8},  {148, 6},
+    {139, 9},  {80, 8},   {98, 8},   {66, 6},   {198, 8},  {86, 8},   {60, 10},
+    {14, 9},   {122, 8},  {22, 9},   {38, 9},   {3, 8},    {209, 12}, {157, 6},
+    {110, 8},  {70, 6},   {128, 8},  {26, 9},   {42, 9},   {5, 8},    {193, 6},
+    {82, 6},   {50, 9},   {9, 8},    {118, 6},  {17, 8},   {33, 8},   {0, 6},
+    {209, 12}, {209, 12}, {209, 12}, {209, 12}, {189, 8},  {152, 7},  {164, 7},
+    {145, 3},  {201, 8},  {88, 8},   {106, 8},  {69, 7},   {124, 8},  {75, 7},
+    {93, 7},   {64, 4},   {209, 12}, {158, 7},  {112, 8},  {71, 7},   {130, 8},
+    {28, 9},   {44, 9},   {6, 8},    {194, 7},  {83, 7},   {52, 9},   {10, 8},
+    {119, 7},  {18, 8},   {34, 8},   {1, 7},    {209, 12}, {209, 12}, {173, 7},
+    {148, 6},  {136, 8},  {79, 7},   {97, 7},   {66, 6},   {197, 7},  {85, 7},
+    {56, 9},   {12, 8},   {121, 7},  {20, 8},   {36, 8},   {2, 7},    {209, 12},
+    {157, 6},  {109, 7},  {70, 6},   {127, 7},  {24, 8},   {40, 8},   {4, 7},
+    {193, 6},  {82, 6},   {48, 8},   {8, 7},    {118, 6},  {16, 7},   {32, 7},
+    {0, 6}};
+
+
+// 1 byte for length, 16 bytes for mask
+ATTRIBUTE_ALIGNED(4096) jubyte StubRoutines::aarch64::_pack_1_2_3_utf8_bytes[256][17] = {
+    {12, 2, 3, 1, 6, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80},
+    {9, 6, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {11, 3, 1, 6, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 6, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 2, 3, 1, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {11, 2, 3, 1, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {10, 3, 1, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 7, 5, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {10, 2, 3, 1, 4, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {7, 4, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {9, 3, 1, 4, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 0, 4, 10, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 2, 3, 1, 6, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 6, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 6, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 6, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 2, 3, 1, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {8, 2, 3, 1, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 7, 5, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 2, 3, 1, 4, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 4, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 4, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 4, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {11, 2, 3, 1, 6, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 6, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {10, 3, 1, 6, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 6, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 2, 3, 1, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {10, 2, 3, 1, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {7, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 3, 1, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 0, 7, 5, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 2, 3, 1, 4, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 4, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 4, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 4, 11, 9, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {10, 2, 3, 1, 6, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {7, 6, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 3, 1, 6, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 0, 6, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 2, 3, 1, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {9, 2, 3, 1, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 7, 5, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 2, 3, 1, 4, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 4, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 4, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 4, 8, 14, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {9, 2, 3, 1, 6, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 6, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 6, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 6, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 2, 3, 1, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {8, 2, 3, 1, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 7, 5, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 2, 3, 1, 4, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 4, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 4, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 4, 10, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 2, 3, 1, 6, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {3, 6, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 6, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 6, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 2, 3, 1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80, 0x80},
+    {2, 3, 1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {1, 0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80, 0x80},
+    {5, 2, 3, 1, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {2, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {4, 3, 1, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 0, 7, 5, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {4, 2, 3, 1, 4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {1, 4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80, 0x80},
+    {3, 3, 1, 4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {2, 0, 4, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {8, 2, 3, 1, 6, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 6, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 6, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 6, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 2, 3, 1, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {2, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {4, 3, 1, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 0, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {7, 2, 3, 1, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 3, 1, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 0, 7, 5, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 2, 3, 1, 4, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {3, 4, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 4, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 4, 11, 9, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 2, 3, 1, 6, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 6, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 3, 1, 6, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 0, 6, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 2, 3, 1, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {1, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80, 0x80},
+    {3, 3, 1, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {2, 0, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 2, 3, 1, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {3, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 7, 5, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 2, 3, 1, 4, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {2, 4, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {4, 3, 1, 4, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 0, 4, 8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {11, 2, 3, 1, 6, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 6, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {10, 3, 1, 6, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 6, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 2, 3, 1, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {10, 2, 3, 1, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {7, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 3, 1, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 0, 7, 5, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 2, 3, 1, 4, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 4, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 4, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 4, 10, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 2, 3, 1, 6, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 6, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 6, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 6, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 2, 3, 1, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {2, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80, 0x80},
+    {4, 3, 1, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {3, 0, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {7, 2, 3, 1, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 7, 5, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 2, 3, 1, 4, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 4, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 4, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 4, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {10, 2, 3, 1, 6, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {7, 6, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 3, 1, 6, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 0, 6, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 2, 3, 1, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {9, 2, 3, 1, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 7, 5, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 2, 3, 1, 4, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 4, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 4, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 4, 11, 9, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {9, 2, 3, 1, 6, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 6, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 6, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 6, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 2, 3, 1, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {8, 2, 3, 1, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 7, 5, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 2, 3, 1, 4, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 4, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 4, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 4, 8, 15, 13, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {10, 2, 3, 1, 6, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {7, 6, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {9, 3, 1, 6, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 0, 6, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 2, 3, 1, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {9, 2, 3, 1, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 7, 5, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {8, 2, 3, 1, 4, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 4, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 4, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 4, 10, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 2, 3, 1, 6, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 6, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 3, 1, 6, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 0, 6, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 2, 3, 1, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {1, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80, 0x80},
+    {3, 3, 1, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {2, 0, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 2, 3, 1, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {3, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 7, 5, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 2, 3, 1, 4, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {2, 4, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {4, 3, 1, 4, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 0, 4, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {9, 2, 3, 1, 6, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {6, 6, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 3, 1, 6, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {7, 0, 6, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 2, 3, 1, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {8, 2, 3, 1, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 7, 5, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 2, 3, 1, 4, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 4, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {6, 3, 1, 4, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {5, 0, 4, 11, 9, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {8, 2, 3, 1, 6, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 6, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {7, 3, 1, 6, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {6, 0, 6, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 2, 3, 1, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {2, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {4, 3, 1, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {3, 0, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {7, 2, 3, 1, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {4, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 3, 1, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {5, 0, 7, 5, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {6, 2, 3, 1, 4, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {3, 4, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80, 0x80},
+    {5, 3, 1, 4, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80},
+    {4, 0, 4, 8, 12, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80, 0x80}};
+
+// 1 byte for length, 16 bytes for mask
+ATTRIBUTE_ALIGNED(4096) jubyte StubRoutines::aarch64::_pack_1_2_utf8_bytes[256][17] = {
+    {16, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14},
+    {15, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80},
+    {15, 1, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80},
+    {14, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {15, 1, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80},
+    {14, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {14, 1, 0, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {15, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80},
+    {14, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {14, 1, 0, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {15, 1, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80},
+    {14, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {14, 1, 0, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 4, 7, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 4, 7, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 7, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {15, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80},
+    {14, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {14, 1, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 4, 7, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 7, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 7, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 7, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {15, 1, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80},
+    {14, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {14, 1, 0, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 4, 6, 9, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 6, 8, 11, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 6, 9, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 6, 8, 10, 13, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 5, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 5, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 5, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 5, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 6, 9, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 6, 8, 11, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 3, 2, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 3, 2, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 6, 9, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 2, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 2, 4, 6, 8, 10, 12, 15, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {15, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80},
+    {14, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {14, 1, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80},
+    {13, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 4, 7, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 7, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 7, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 7, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 5, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 5, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 5, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 5, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 7, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 7, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 3, 2, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 3, 2, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 7, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 2, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 2, 4, 7, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {14, 1, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80},
+    {13, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 2, 5, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 5, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 5, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 5, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 5, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {13, 1, 0, 3, 2, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 4, 6, 9, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 6, 8, 11, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 3, 2, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 3, 2, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 6, 9, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 2, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 2, 4, 6, 8, 10, 13, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {13, 1, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80},
+    {12, 0, 3, 2, 5, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 5, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 5, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 2, 5, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 2, 5, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 5, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 5, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 5, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 3, 2, 5, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 3, 2, 5, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 5, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 5, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 2, 5, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 2, 5, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {12, 1, 0, 3, 2, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80},
+    {11, 0, 3, 2, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 3, 2, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 3, 2, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {11, 1, 0, 2, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 2, 4, 6, 9, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 2, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 2, 4, 6, 8, 11, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80},
+    {11, 1, 0, 3, 2, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 0, 3, 2, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 3, 2, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 3, 2, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {10, 1, 0, 2, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 0, 2, 4, 6, 9, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {9, 1, 0, 2, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
+    {8, 0, 2, 4, 6, 8, 10, 12, 14, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+     0x80}};
+
+#endif // CPU_AARCH64_SIMDUTF_UTF_TABLES_HPP
diff --git a/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp b/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp
index e0ca01ba6..e754ef304 100644
--- a/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/stubDeclarations_aarch64.hpp
@@ -80,6 +80,14 @@
   do_stub(compiler, count_positives_long)                               \
   do_arch_entry(aarch64, compiler, count_positives_long,                \
                 count_positives_long, count_positives_long)             \
+  do_stub(compiler, convert_masked_utf8_to_utf16)                       \
+  do_arch_entry(aarch64, compiler, convert_masked_utf8_to_utf16,        \
+                convert_masked_utf8_to_utf16,                           \
+                convert_masked_utf8_to_utf16)                           \
+  do_stub(compiler, scalar_convert_utf8_to_utf16)                       \
+  do_arch_entry(aarch64, compiler, scalar_convert_utf8_to_utf16,        \
+                scalar_convert_utf8_to_utf16,                           \
+                scalar_convert_utf8_to_utf16)                           \
   do_stub(compiler, compare_long_string_LL)                             \
   do_arch_entry(aarch64, compiler, compare_long_string_LL,              \
                 compare_long_string_LL, compare_long_string_LL)         \
diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
index a0d1e22ff..146969702 100644
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
@@ -8736,6 +8736,609 @@ class StubGenerator: public StubCodeGenerator {
     return entry;
   }
 
+  address generate_scalar_convert_utf8_to_utf16() {
+
+    int dcache_line = VM_Version::dcache_line_size();
+
+    Label CNV_LOOP, CHK_3BYTES, NO_FAST, NO_FAST_2, NON_ASCII_LOOP, U8_2BT, U8_3BT, U8_4BT, IS_ERR, DONE;
+    // iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, iRegI_R0 result,
+    Register dst = r1, src = r2, len = r3, res=r0;
+
+    Register maxSrc = r10; // it's calculated already
+    Register rTemp = rscratch1;
+    Register bytesLeft = r11;
+    Register dat0 = r12;
+    Register dat1 = r13;
+    Register dat2 = r14;
+    // Register actPos = r15;
+    Register tstChn1 = r15; // same register as actPos, used after actPos usage expired
+    Register dat3 = rscratch2;
+    Register errInfo = r16;
+
+    FloatRegister vIn0 = v0; // order of registers can not be changed !!!
+    FloatRegister vCalcZero = v1; // rename register to describe usage as "zeros"
+    FloatRegister vCalcC0 = v2; // vIn1 - vIn3 are free to use now, because we are working on 1 chunk only
+    FloatRegister vCalcSuzie = v3;
+    FloatRegister vIn2 = v4;
+    FloatRegister vCalcJack = v5;
+    FloatRegister vIn3 = v6;
+    FloatRegister vCalcMartha = v7;
+    FloatRegister vCalcGreg = v8;
+    FloatRegister vCalcViki = v9;
+    FloatRegister vErrors = v10;
+
+    uint8_t idx;
+
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "scalar_convert_utf8_to_utf16");
+
+    address entry = __ pc();
+    // based on  https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/scalar/utf8_to_utf16/utf8_to_utf16.h#L10
+    // with additional fastpaths
+    __ enter();
+
+    __ movi(vCalcZero, __ T16B, 0); // to use in fastascii
+    __ movi(vCalcC0, __ T16B, 0xC0); // to check chinafastpath
+
+    // __ sub(bytesLeft,len, actPos);
+
+    __ mov(tstChn1, 0xFF00FFFF00FFFF00);
+
+    // __ add(maxSrc,src,bytesLeft);
+
+    __ BIND(CNV_LOOP);
+    __ sub(bytesLeft, maxSrc, src);
+    __ cbz(bytesLeft, DONE);
+
+    __ cmpw(bytesLeft, 16);
+    __ br(Assembler::LT, NO_FAST); // there must be at least 1 simd vector to fill to use fastpaths
+
+    __ ld1(vIn0, __ T16B, src);
+    __ umov(dat0, vIn0, __ D, 0); // return vminvq_s8(value);
+    __ andr(rTemp, dat0, 0x8080808080808080);
+    __ cbnz(rTemp, CHK_3BYTES);
+    __ umov(dat1, vIn0, __ D, 1);
+    __ andr(rTemp, dat1, 0x8080808080808080);
+    __ cbnz(rTemp, CHK_3BYTES);
+
+      __ st2(vIn0, vCalcZero, __ T16B, __ post(dst, 32)); // just store data mixing with zeros
+      __ add(src, src, 16);
+      __ add(res, res, 16);
+    __ b(CNV_LOOP);
+
+    __ BIND(CHK_3BYTES);
+
+    __ cm(__ GT, vCalcSuzie, __ T16B, vCalcC0, vIn0); // compare with -64
+    __ umov(dat0, vCalcSuzie, __ D, 0);
+
+    __ eor(dat0, dat0, tstChn1);
+    __ cbnz(dat0, NO_FAST);
+
+    __ umov(dat1, vCalcSuzie, __ D, 1);
+    __ mov(rTemp, 0x000000FFFFFFFFFF); // including 13th byte because after 3 3-byte units there can be 1 4-byte unit
+    __ andr(dat1, dat1, rTemp);
+    __ mov(rTemp, 0x00000000FFFF00FF); // 0xFF00FFFF00000000
+    __ eor(dat1, dat1, rTemp);
+    __ cbnz(dat1, NO_FAST);
+
+    // 3 bytes fastpath
+    // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/implementation.cpp#L32
+      __ mov(rTemp, 0x0B09080605030200); // sh = {0, 2, 3, 5, 6, 8, 9, 11    , 1, 1, 4, 4, 7, 7, 10, 10};
+      __ fmovd(vCalcSuzie, rTemp);
+      __ mov(rTemp, 0x0A0A070704040101);
+      __ fmovd(vCalcJack, rTemp);
+      __ ins(vCalcSuzie, __ D, vCalcJack, 1, 0);
+
+      __ tbl(vCalcSuzie, __ T16B, vIn0, 1, vCalcSuzie); // perm
+
+      __ umov(rTemp, vCalcSuzie, __ D, 0); // perm_low
+      __ fmovd(vCalcJack, rTemp);
+
+      __ umov(rTemp, vCalcSuzie, __ D, 1); // perm_high
+      __ fmovd(vCalcGreg, rTemp);
+
+      __ sli(vCalcGreg, __ T4H, vCalcJack, 6); // mid_high
+      __ rev16(vCalcJack, __ T8B, vCalcJack); // low
+
+      __ sli(vCalcJack, __ T4H, vCalcGreg, 6); // composed
+
+      __ st1(vCalcJack, __ T8B, __ post(dst, 8));
+
+      __ add(src, src, 12);
+      __ add(res, res, 4); // We wrote 4 16-bit characters.
+    __ b(CNV_LOOP);
+
+    __ BIND(NO_FAST);
+
+      __ cmpw(bytesLeft, 8);
+      __ br(Assembler::LT, NO_FAST_2); // there must be at least 1 simd vector to fill to use fastpaths
+
+      __ ld1(vIn0, __ T8B, src);
+      __ umov(dat0, vIn0, __ D, 0); // return vminvq_s8(value);
+      __ andr(rTemp, dat0, 0x8080808080808080);
+      __ cbnz(rTemp, NO_FAST_2);
+
+      __ st2(vIn0, vCalcZero, __ T8B, __ post(dst, 16)); // just store data mixing with zeros
+      __ add(src, src, 8);
+      __ add(res, res, 8);
+
+      __ b(CNV_LOOP);
+
+    __ BIND(NO_FAST_2);
+
+      __ ldrb(dat0, __ post(src, 1)); // get leading_byte
+
+      __ cmpw(dat0, 0b10000000);
+      __ br(Assembler::GE, U8_2BT);
+      __ strh(dat0, __ post(dst, 2)); // just store 2 bytes when ascii (during ldrb dat0 is 0 extended)
+      __ add(res, res, 1);
+
+      __ b(CNV_LOOP);
+    __ BIND(U8_2BT);
+      __ mov(rTemp, dat0);
+      __ andr(rTemp, rTemp, 0b11100000);
+      __ cmpw(rTemp, 0b11000000);
+      __ br(Assembler::NE, U8_3BT);
+      // process 2 byte unit
+      __ cmpw(bytesLeft, 1);
+        __ br(Assembler::LE, IS_ERR);
+        __ ldrb(dat1, __ post(src, 1));
+        __ mov(rTemp, dat1);
+        __ andr(rTemp, rTemp, 0b11000000);
+        __ cmpw(rTemp, 0b10000000);
+        __ br(Assembler::NE, IS_ERR);
+
+        __ andr(dat0, dat0, 0b00011111);
+        __ lsl(dat0, dat0, 6);
+        __ andr(dat1, dat1, 0b00111111);
+        __ orr(rTemp, dat0, dat1);
+
+        __ cmpw(rTemp, 0x80);
+        __ br(Assembler::LO, IS_ERR);
+        __ cmpw(rTemp, 0x7ff);
+        __ br(Assembler::GT, IS_ERR);
+        __ strh(rTemp, __ post(dst, 2));
+        __ add(res, res, 1); // We stored 1 2-byte unit
+
+        __ b(CNV_LOOP);
+
+    __ BIND(U8_3BT);
+      __ mov(rTemp, dat0);
+      __ andr(rTemp, rTemp, 0b11110000);
+      __ cmpw(rTemp, 0b11100000);
+      __ br(Assembler::NE, U8_4BT);
+      // process 3 byte unit
+      __ cmpw(bytesLeft, 2);
+      __ br(Assembler::LE, IS_ERR);
+
+        __ ldrb(dat1, __ post(src, 1));
+        __ mov(rTemp, dat1);
+        __ andr(rTemp, rTemp, 0b11000000);
+        __ cmpw(rTemp, 0b10000000);
+        __ br(Assembler::NE, IS_ERR);
+
+        __ ldrb(dat2, __ post(src, 1));
+        __ mov(rTemp, dat2);
+        __ andr(rTemp, rTemp, 0b11000000);
+        __ cmpw(rTemp, 0b10000000);
+        __ br(Assembler::NE, IS_ERR);
+
+        __ andr(dat0, dat0, 0b00001111);
+        __ andr(dat1, dat1, 0b00111111);
+        __ andr(dat2, dat2, 0b00111111);
+
+        __ lsl(dat0, dat0, 12);
+        __ lsl(dat1, dat1, 6);
+        __ orr(rTemp, dat0, dat1);
+        __ orr(rTemp, rTemp, dat2);
+
+        __ mov(dat0, rTemp);
+
+        __ cmpw(rTemp, 0x800);
+          __ br(Assembler::LO, IS_ERR);
+
+
+        {
+          Label CHK_2, CHK_OK;
+
+          __ mov(dat3, 0xd7ff);
+          __ cmp(rTemp, dat3);
+          __ br(Assembler::HI, CHK_2);
+          __ b(CHK_OK);
+
+          __ BIND(CHK_2);
+          __ mov(dat3, 0xe000);
+          __ cmp(rTemp, dat3);
+          __ br(Assembler::LO, IS_ERR);
+
+          __ BIND(CHK_OK);
+        }
+        __ lsr(rTemp, rTemp, 16);
+        __ cbnz(rTemp, IS_ERR);
+
+        __ strh(dat0, __ post(dst, 2));
+
+        __ add(res, res, 1);
+        __ b(CNV_LOOP);
+
+
+    __ BIND(U8_4BT);
+    // process 4 byte unit
+    __ mov(rTemp, dat0);
+    __ andr(rTemp, rTemp, 0b11111000);
+    __ cmpw(rTemp, 0b11110000);
+    __ br(Assembler::NE, IS_ERR);
+
+    __ cmpw(bytesLeft, 3);
+    __ br(Assembler::LE, IS_ERR);
+
+      __ ldrb(dat1, __ post(src, 1));
+      __ mov(rTemp, dat1);
+      __ andr(rTemp, rTemp, 0b11000000);
+      __ cmpw(rTemp, 0b10000000);
+      __ br(Assembler::NE, IS_ERR);
+
+      __ ldrb(dat2, __ post(src, 1));
+      __ mov(rTemp, dat2);
+      __ andr(rTemp, rTemp, 0b11000000);
+      __ cmpw(rTemp, 0b10000000);
+      __ br(Assembler::NE, IS_ERR);
+
+      __ ldrb(dat3, __ post(src, 1));
+      __ mov(rTemp, dat3);
+      __ andr(rTemp, rTemp, 0b11000000);
+      __ cmpw(rTemp, 0b10000000);
+      __ br(Assembler::NE, IS_ERR);
+
+        __ andr(dat0, dat0, 0b00000111);
+        __ andr(dat1, dat1, 0b00111111);
+        __ andr(dat2, dat2, 0b00111111);
+        __ andr(dat3, dat3, 0b00111111);
+
+        __ lsl(dat0, dat0, 18);
+        __ lsl(dat1, dat1, 12);
+        __ lsl(dat2, dat2, 6);
+        __ orr(rTemp, dat0, dat1);
+        __ orr(rTemp, rTemp, dat2);
+        __ orr(rTemp, rTemp, dat3);
+
+        __ mov(dat2, rTemp);
+
+        __ mov(rTemp, 0xffff);
+        __ cmpw(dat2, rTemp);
+        __ br(Assembler::LE, IS_ERR);
+        __ mov(rTemp, 0x10ffff);
+        __ cmpw(dat2, rTemp);
+        __ br(Assembler::GT, IS_ERR);
+
+        __ sub(dat2, dat2, 0x10000);
+        __ mov(dat1, dat2);
+        __ lsr(dat1, dat1, 10);
+        __ add(dat1, dat1, 0xD800);
+        __ strh(dat1, __ post(dst, 2));
+        __ andr(dat2, dat2, 0x3FF);
+        __ add(dat2, dat2, 0xDC00);
+        __ strh(dat2, __ post(dst, 2));
+
+        __ add(res, res, 2);
+    __ b(CNV_LOOP);
+
+    __ BIND(IS_ERR);
+      __ mov(errInfo, -5);
+
+    __ BIND(DONE);
+
+      __ leave();
+      __ ret(lr);
+
+    return entry;
+  }
+
+  address generate_convert_masked_utf8_to_utf16() {
+
+    int dcache_line = VM_Version::dcache_line_size();
+
+    Label CHK_8ASCII, CHK_3BYTES, CHK_2BYTES, CHK_4CU, CHK_3CU, CHK_3_1_4CU, IS_ERR, NO_FASTPATH, DONE;
+    // iRegP_R2 src, iRegP_R1 dst, iRegI_R3 len, iRegI_R0 result,
+    Register dst = r1, src = r2, len = r3, res=r0;
+
+    // It's assumed that cMask, register is filled by caller
+    Register rTemp = rscratch1;
+    Register cMask = r11;
+    Register cnvTemp = r12;
+    Register lookAddr = r14;
+    Register idx = rscratch2;
+
+    FloatRegister vIn0 = v0; // order of registers can not be changed !!!
+    FloatRegister vCalcJohn = v1;
+    FloatRegister vIn1 = v2;
+    FloatRegister vCalcSuzie = v3;
+    FloatRegister vIn2 = v4;
+    FloatRegister vCalcJack = v5;
+    FloatRegister vIn3 = v6;
+    FloatRegister vCalcMartha = v7;
+    FloatRegister vCalcGreg = v8;
+    FloatRegister vCalcViki = v9;
+    FloatRegister vErrors = v10;
+
+    uint64_t offset;
+
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "convert_masked_utf8_to_utf16");
+
+    address entry = __ pc();
+
+    __ enter();
+
+    // __ movi(vCalcJohn, __ T16B, 0);
+
+    __ ld1(vIn0, __ T16B, src);
+    // checking for fastpaths
+    // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/arm_convert_utf8_to_utf16.cpp#L24
+    __ andr(rTemp, cMask, 0xFFFF);
+    __ sub(rTemp, rTemp, 0xFFFF);
+    __ cbnz(rTemp, CHK_3BYTES);
+      __ movi(vCalcJohn, __ T16B, 0);
+      __ st2(vIn0, vCalcJohn, __ T16B, __ post(dst, 32)); // ascii fastpath, just store mixing with 0
+      __ add(res, res, 16); // We wrote 16 16-bit characters.
+      __ mov(cnvTemp, 16); // We consumed 16 bytes.
+      __ b(DONE);
+
+    __ BIND(CHK_3BYTES);
+    __ andr(cnvTemp, cMask, 0xFFF);
+    // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/arm_convert_utf8_to_utf16.cpp#L35
+    __ cmpw(cnvTemp, 0x924);
+    __ br(Assembler::NE, CHK_8ASCII);
+    // 3 bytes fastpath
+    // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/implementation.cpp#L32
+    __ mov(rTemp, 0x0B09080605030200); // sh = {0, 2, 3, 5, 6, 8, 9, 11    , 1, 1, 4, 4, 7, 7, 10, 10};
+      __ fmovd(vCalcSuzie, rTemp);
+      __ mov(rTemp, 0x0A0A070704040101);
+      __ fmovd(vCalcJack, rTemp);
+      __ ins(vCalcSuzie, __ D, vCalcJack, 1, 0);
+
+      __ tbl(vCalcSuzie, __ T16B, vIn0, 1, vCalcSuzie);
+
+      __ umov(rTemp, vCalcSuzie, __ D, 0);
+      __ fmovd(vCalcJack, rTemp);
+
+      __ umov(rTemp, vCalcSuzie, __ D, 1);
+      __ fmovd(vCalcGreg, rTemp);
+
+      __ sli(vCalcGreg, __ T4H, vCalcJack, 6);
+      __ rev16(vCalcJack, __ T8B, vCalcJack);
+
+      __ sli(vCalcJack, __ T4H, vCalcGreg, 6);
+
+      __ st1(vCalcJack, __ T8B, __ post(dst, 8));
+
+      __ add(res, res, 4); // We wrote 4 characters.
+      __ mov(cnvTemp, 12); // We consumed 12 utf8 bytes.
+      __ b(DONE);
+
+    __ BIND(CHK_8ASCII);
+    __ andr(rTemp, cMask, 0x00FF);
+    __ sub(rTemp, rTemp, 0x00FF);
+    __ cbnz(rTemp, CHK_2BYTES);
+      __ movi(vCalcJohn, __ T16B, 0);
+      __ st2(vIn0, vCalcJohn, __ T8B, __ post(dst, 16)); // ascii fastpath, just store mixing with 0
+      __ add(res, res, 8); // We wrote 8 16-bit characters.
+      __ mov(cnvTemp, 8); // We consumed 8 bytes.
+      __ b(DONE);
+
+    __ BIND(CHK_2BYTES);
+    __ andr(rTemp, cMask, 0xFFF);
+    __ cmpw(rTemp, 0xaaa);
+    __ br(Assembler::NE, NO_FASTPATH);
+    // 2 bytes fastpath
+    // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/implementation.cpp#L63
+      __ rev16(vCalcSuzie, __ T16B, vIn0);
+
+      __ movi(vCalcJack, __ T8H, 0x1f);
+      __ andr(vCalcJack, __ T16B, vIn0, vCalcJack);
+      __ sli(vCalcSuzie, __ T8H, vCalcJack, 6);
+
+      __ st1(vCalcSuzie, __ T16B, dst);
+      __ add(dst, dst, 12);
+
+      __ add(res, res, 6); // We wrote 6 16-bit characters
+      __ mov(cnvTemp, 12); // We consumed 12 bytes.
+
+      __ b(DONE);
+
+    __ BIND(NO_FASTPATH);
+
+    // there is no fastpaths, let's use lookup table solution
+    __ adrp(lookAddr, ExternalAddress(StubRoutines::aarch64::utf8bigindex_adr()), offset);
+    __ add(lookAddr, lookAddr, offset);
+
+    __ mov(rTemp, 2);
+    __ mul(rTemp, cnvTemp, rTemp);
+    __ add(rTemp, lookAddr, rTemp);
+    __ ldrb(idx, rTemp); // const uint8_t idx
+
+    __ add(rTemp, rTemp, 1);
+    __ ldrb(cnvTemp, rTemp); // utf8bigindex[input_utf8_end_of_code_point_mask][1];
+
+    __ cmpw(idx, 209);
+    __ br(Assembler::GE, IS_ERR);
+
+    __ adrp(lookAddr, ExternalAddress(StubRoutines::aarch64::shufutf8_adr()), offset);
+    __ add(lookAddr, lookAddr, offset);
+
+    __ mov(rTemp, 16); // prescending table is: const uint8_t shufutf8[209][16]
+    __ mul(rTemp, idx, rTemp);
+    __ add(rTemp, lookAddr, rTemp);
+    __ ld1(vCalcSuzie, __ T16B, rTemp);
+
+    __ cmpw(idx, 0x40); // if (idx < 64) { // SIX (6) input code-code units
+    __ br(Assembler::GE, CHK_4CU);
+    // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/implementation.cpp#L83
+      __ tbl(vCalcSuzie, __ T16B, vIn0, 1, vCalcSuzie); // perm
+
+      __ movi(vCalcJack, __ T8H, 0x7F);
+      __ andr(vCalcJack, __ T16B, vCalcSuzie, vCalcJack); // ascii 6 or 7 bits
+
+      __ movi(vCalcMartha, __ T8H, 0x1F, 8);
+      __ andr(vCalcMartha, __ T16B, vCalcSuzie, vCalcMartha); // highbyte 5 bits
+
+      __ usra(vCalcJack, __ T8H, vCalcMartha, 2); // composed
+
+      __ st1(vCalcJack, __ T16B, dst);
+      __ add(dst, dst, 12);
+
+      __ add(res, res, 6); // We wrote 6 16-bit characters
+      // bytes consumed put to cnvTemp from utf8bigindex[input_utf8_end_of_code_point_mask][1];
+      __ b(DONE);
+
+    __ BIND(CHK_4CU);
+    __ cmpw(idx, 0x91); // else if (idx < 145)
+      __ br(Assembler::GE, CHK_3CU);
+      // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/arm_convert_utf8_to_utf16.cpp#L86C5-L86C38
+      __ tbl(vCalcSuzie, __ T16B, vIn0, 1, vCalcSuzie); // perm
+
+      __ xtn(vCalcJack, __ T4H, vCalcSuzie, __ T4S); // lowperm
+
+      __ movi(vCalcMartha, __ T4H, 0xFF); // middlebyte
+      __ bic(vCalcMartha, __ T16B, vCalcJack, vCalcMartha);
+
+      __ movi(vCalcGreg, __ T4H, 0x7F); // ascii
+      __ andr(vCalcGreg, __ T16B, vCalcGreg, vCalcJack);
+
+      __ ushr(vCalcSuzie, __ T4S, vCalcSuzie, 16); // highperm
+      __ xtn(vCalcSuzie, __ T4H, vCalcSuzie, __ T4S);
+
+      __ usra(vCalcGreg, __ T4H, vCalcMartha, 2); // middlelow
+
+      __ sli(vCalcGreg, __ T4H, vCalcSuzie, 12); // composed
+
+      __ st1(vCalcGreg, __ T8B, __ post(dst, 8));
+
+      __ add(res, res, 4); // We wrote 4 16-bit codepoints
+      // bytes consumed put to cnvTemp from utf8bigindex[input_utf8_end_of_code_point_mask][1];
+      __ b(DONE);
+
+    __ BIND(CHK_3CU);
+    __ cmpw(idx, 0xD1); // else if (idx < 209)
+      __ br(Assembler::GE, IS_ERR);
+      __ andr(rTemp, cMask, 0xFFF);
+      __ cmpw(rTemp, 0x888);
+      __ br(Assembler::NE, CHK_3_1_4CU);
+      // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/arm_convert_utf8_to_utf16.cpp#L134
+
+        __ rev16(vCalcSuzie, __ T16B, vIn0); // swap
+
+        __ shl(vCalcJack, __ T16B, vCalcSuzie, 2); // shift
+
+        __ mov(rTemp, 0xDC00E7C0DC00E7C0); // magic
+        __ fmovd(vCalcMartha, rTemp);
+        __ ins(vCalcMartha, __ D, vCalcMartha, 1, 0);
+
+        __ mov(vCalcGreg, __ T16B, vCalcJack); // trail
+        __ movi(vCalcViki, __ T4S, 0xFF, 8);
+        __ bit(vCalcGreg, __ T16B, vCalcSuzie, vCalcViki);
+
+        __ usra(vCalcMartha, __ T4S, vCalcJack, 30); // magic_with_low_2
+        __ sli(vCalcSuzie, __ T8H, vIn0, 6); // lead
+
+        __ movi(vCalcViki, __ T4S, 0xFC, 24);
+        __ bic(vCalcSuzie, __ T16B, vCalcSuzie, vCalcViki);
+
+        __ mov(rTemp, 0x0000FFFF);
+        __ dup(vCalcViki, __ T4S, rTemp);
+        __ bit(vCalcSuzie, __ T16B, vCalcGreg, vCalcViki); // blend
+
+        __ addv(vCalcSuzie, __ T8H, vCalcSuzie, vCalcMartha); // composed
+
+        __ st1(vCalcSuzie, __ T16B, dst); // store from register
+        __ add(dst, dst, 12); // We wrote 3 32-bit surrogate pairs. so 3x4
+        __ add(res, res, 6); // utf16_output += 6;
+
+      __ b(DONE);
+
+      __ BIND(CHK_3_1_4CU);
+      // https://github.com/simdutf/simdutf/blob/36e2d53e8f182ac47047a024db653407d28c9cb3/src/arm64/arm_convert_utf8_to_utf16.cpp#L216
+        __ tbl(vCalcSuzie, __ T16B, vIn0, 1, vCalcSuzie); // perm
+
+        __ movi(vCalcMartha, __ T4S, 0x7F);
+        __ andr(vCalcMartha, __ T16B, vCalcSuzie, vCalcMartha); // ascii
+
+        __ shl(vCalcJack, __ T4S, vCalcSuzie, 2); // middlehigh
+
+        __ movi(vCalcGreg, __ T4S, 0x3F, 8);
+        __ andr(vCalcGreg, __ T16B, vCalcSuzie, vCalcGreg); // middlebyte
+
+        __ movi(vCalcViki, __ T4S, 0xFF, 24);
+        __ bit(vCalcJack, __ T16B, vCalcSuzie, vCalcViki); // ab
+
+        __ mov(rTemp, 0xFFFC0000);
+        __ dup(vCalcViki, __ T4S, rTemp);
+        __ shl(vCalcGreg, __ T4S, vCalcGreg, 4);
+        __ bit(vCalcGreg, __ T16B, vCalcJack, vCalcViki); // abc
+
+        __ usra(vCalcMartha, __ T4S, vCalcGreg, 6); // composed
+        __ mov(vCalcJack, __ T16B, vCalcMartha);
+
+        __ mov(rTemp, 0xFFFF0000);
+        __ dup(vCalcViki, __ T4S, rTemp);
+        __ bit(vCalcJack, __ T16B, vCalcGreg, vCalcViki);  // mixed
+
+        __ movi(vCalcViki, __ T4S, 0xFC, 8);
+        __ bic(vCalcJack, __ T16B, vCalcJack, vCalcViki); // masked_pair
+
+        __ mov(rTemp, 0xE7C0DC00);
+        __ dup(vCalcGreg, __ T4S, rTemp); // magic
+
+        __ addv(vCalcJack, __ T8H, vCalcJack, vCalcGreg); // surrogates
+
+        __ mov(vCalcGreg, __ T16B, vCalcSuzie);
+        __ cm(Assembler::LT, vCalcGreg, __ T4S,vCalcGreg); // is_pair
+
+        __ bit(vCalcMartha, __ T16B, vCalcJack, vCalcGreg);  // selected
+
+        {
+
+          int i=0;
+          for (i = 0; i < 3; i++) {
+            Label TST_FAIL, LOOP_END;
+            __ umov(rTemp, vCalcSuzie, __ S, i); // if ((permbuffer[i] & 0xf8000000) == 0xf0000000) {
+            __ umov(idx, vCalcMartha, __ S, i); // // this is  buffer[i]
+            __ andr(rTemp, rTemp, 0xf8000000);
+            __ mov(lookAddr, 0xf0000000);
+            __ cmp(rTemp, lookAddr);
+            __ br(Assembler::NE, TST_FAIL);
+              __ mov(rTemp, idx);
+              __ lsr(rTemp, rTemp, 16);
+              __ strh(rTemp, __ post(dst, 2));
+              __ andr(idx, idx, 0xFFFF);
+              __ strh(idx, __ post(dst, 2));
+              __ add(res, res, 2);
+
+              __ b(LOOP_END);
+            __ BIND(TST_FAIL);
+              __ andr(idx, idx, 0xFFFF);
+              __ str(idx, __ post(dst, 2));
+              __ add(res, res, 1);
+            __ BIND(LOOP_END);
+
+          }
+        }
+
+      __ b(DONE);
+
+    __ BIND(IS_ERR);
+      __ mov(cnvTemp, -3); // just return -3 and go out
+
+
+    __ BIND(DONE);
+    __ leave();
+    __ ret(lr);
+
+    return entry;
+  }
+
   address generate_dsin_dcos(bool isCos) {
     __ align(CodeEntryAlignment);
     StubGenStubId stub_id = (isCos ? StubGenStubId::dcos_id : StubGenStubId::dsin_id);
@@ -11769,6 +12372,10 @@ class StubGenerator: public StubCodeGenerator {
     // countPositives stub for large arrays.
     StubRoutines::aarch64::_count_positives = generate_count_positives(StubRoutines::aarch64::_count_positives_long);
 
+    StubRoutines::aarch64::_convert_masked_utf8_to_utf16 = generate_convert_masked_utf8_to_utf16();
+
+    StubRoutines::aarch64::_scalar_convert_utf8_to_utf16 = generate_scalar_convert_utf8_to_utf16();
+
     generate_compare_long_strings();
 
     generate_string_indexof_stubs();
diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp
index fab76c413..78d5bf6d2 100644
--- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp
@@ -48,6 +48,12 @@ STUBGEN_ARCH_ENTRIES_DO(DEFINE_ARCH_ENTRY, DEFINE_ARCH_ENTRY_INIT)
 
 bool StubRoutines::aarch64::_completed = false;
 
+// UTF conversion lookup tables derived from simdutf (https://github.com/simdutf/simdutf).
+// See src/hotspot/share/legal/simdutf.md for licensing details.
+#define STUB_ROUTINES_AARCH64_SIMDUTF_TABLES_IMPL
+#include "simdutf_utf_tables.hpp"
+#undef STUB_ROUTINES_AARCH64_SIMDUTF_TABLES_IMPL
+
 ATTRIBUTE_ALIGNED(64) uint16_t StubRoutines::aarch64::_kyberConsts[] =
 {
     // Because we sometimes load these in pairs, montQInvModR, kyber_q
diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
index 4c942b9f8..11c360332 100644
--- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
@@ -101,6 +101,22 @@ private:
     return nullptr;
   }
 
+  static address pack_1_2_3_utf8_bytes_adr() {
+    return (address) _pack_1_2_3_utf8_bytes;
+  }
+
+  static address pack_1_2_utf8_bytes_adr() {
+    return (address) _pack_1_2_utf8_bytes;
+  }
+
+  static address utf8bigindex_adr() {
+    return (address) _utf8bigindex;
+  }
+
+  static address shufutf8_adr() {
+    return (address) _shufutf8;
+  }
+
   static bool complete() {
     return _completed;
   }
@@ -120,6 +136,10 @@ private:
   static jdouble   _pio2[];
   static jdouble   _dsin_coef[];
   static jdouble  _dcos_coef[];
+  static jubyte _pack_1_2_3_utf8_bytes[256][17];
+  static jubyte _pack_1_2_utf8_bytes[256][17];
+  static jubyte _shufutf8[209][16];
+  static jubyte _utf8bigindex[4096][2];
   // end trigonometric tables block
 };
 
diff --git a/src/hotspot/share/adlc/formssel.cpp b/src/hotspot/share/adlc/formssel.cpp
index b938d5b75..bfd2fc786 100644
--- a/src/hotspot/share/adlc/formssel.cpp
+++ b/src/hotspot/share/adlc/formssel.cpp
@@ -912,7 +912,9 @@ uint InstructForm::oper_input_base(FormDict &globals) {
         strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
         strcmp(_matrule->_rChild->_opType,"StrIndexOfChar")==0 ||
         strcmp(_matrule->_rChild->_opType,"CountPositives")==0 ||
-        strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
+        strcmp(_matrule->_rChild->_opType,"EncodeISOArray") == 0 ||
+        strcmp(_matrule->_rChild->_opType,"DecodeUtf8ToUtf16") == 0 ||
+        strcmp(_matrule->_rChild->_opType,"EncodeUtf8FromUtf16") == 0)) {
         // String.(compareTo/equals/indexOf/hashCode) and Arrays.equals
         // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
         // take 1 control and 1 memory edges.
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index 0e8467289..02933a760 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -263,6 +263,30 @@ void java_lang_String::set_compact_strings(bool value) {
   vmClasses::String_klass()->do_local_static_fields(&fix);
 }
 
+#ifdef AARCH64
+class UTFConversionIntrinsicsFixup : public FieldClosure {
+private:
+  bool _value;
+
+public:
+  UTFConversionIntrinsicsFixup(bool value) : _value(value) {}
+
+  void do_field(fieldDescriptor* fd) {
+    if (fd->name() == vmSymbols::utf_conversion_intrinsics_name()) {
+      oop mirror = fd->field_holder()->java_mirror();
+      assert(fd->field_holder() == vmClasses::String_klass(), "Should be String");
+      assert(mirror != NULL, "String must have mirror already");
+      mirror->bool_field_put(fd->offset(), _value);
+    }
+  }
+};
+
+void java_lang_String::set_utf_conversion_intrinsics(bool value) {
+  UTFConversionIntrinsicsFixup fix(value);
+  vmClasses::String_klass()->do_local_static_fields(&fix);
+}
+#endif // AARCH64
+
 Handle java_lang_String::basic_create(int length, bool is_latin1, TRAPS) {
   assert(_initialized, "Must be initialized");
   assert(CompactStrings || !is_latin1, "Must be UTF16 without CompactStrings");
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 37ca22e92..fe39a740e 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -107,6 +107,10 @@ class java_lang_String : AllStatic {
 
   static void set_compact_strings(bool value);
 
+#ifdef AARCH64
+  static void set_utf_conversion_intrinsics(bool value);
+#endif // AARCH64
+
   static int value_offset() { CHECK_INIT(_value_offset); }
   static int coder_offset() { CHECK_INIT(_coder_offset); }
 
diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp
index baa945cdd..ee02d5e78 100644
--- a/src/hotspot/share/classfile/vmIntrinsics.cpp
+++ b/src/hotspot/share/classfile/vmIntrinsics.cpp
@@ -577,6 +577,8 @@ bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
   case vmIntrinsics::_encodeISOArray:
   case vmIntrinsics::_encodeAsciiArray:
   case vmIntrinsics::_encodeByteISOArray:
+  case vmIntrinsics::_encodeUtf8FromUtf16:
+  case vmIntrinsics::_decodeUtf8ToUtf16:
     if (!SpecialEncodeISOArray) return true;
     break;
   case vmIntrinsics::_getCallerClass:
diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp
index eeefddfed..1bf5e2034 100644
--- a/src/hotspot/share/classfile/vmIntrinsics.hpp
+++ b/src/hotspot/share/classfile/vmIntrinsics.hpp
@@ -428,6 +428,12 @@ class methodHandle;
   do_intrinsic(_encodeAsciiArray,       java_lang_StringCoding, encodeAsciiArray_name, encodeISOArray_signature, F_S)   \
    do_name(     encodeAsciiArray_name,                           "implEncodeAsciiArray")                                \
                                                                                                                         \
+  do_intrinsic(_encodeUtf8FromUtf16,    java_lang_StringCoding, encodeUtf8FromUtf16_name, indexOfI_signature, F_S)      \
+   do_name(     encodeUtf8FromUtf16_name,                         "implEncodeUtf8fromUtf16")                            \
+                                                                                                                        \
+  do_intrinsic(_decodeUtf8ToUtf16,      java_lang_StringCoding, decodeUtf8ToUtf16_name, indexOfI_signature, F_S)        \
+   do_name(     decodeUtf8ToUtf16_name,                           "implDecodeUtf8ToUtf16")                              \
+                                                                                                                        \
   do_class(java_math_BigInteger,                      "java/math/BigInteger")                                           \
   do_intrinsic(_multiplyToLen,      java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_S)             \
    do_name(     multiplyToLen_name,                             "implMultiplyToLen")                                    \
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index a5a8e34e3..726279a35 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -445,6 +445,7 @@ class SerializeClosure;
   template(cache_field_name,                          "cache")                                    \
   template(value_name,                                "value")                                    \
   template(compact_strings_name,                      "COMPACT_STRINGS")                          \
+  template(utf_conversion_intrinsics_name,            "UTF_CONVERSION_INTRINSICS")                \
   template(numberOfLeadingZeros_name,                 "numberOfLeadingZeros")                     \
   template(numberOfTrailingZeros_name,                "numberOfTrailingZeros")                    \
   template(bitCount_name,                             "bitCount")                                 \
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
index 821071812..e410f79f7 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -553,6 +553,10 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
         { { 2, ShenandoahLoad },                  { -1, ShenandoahNone } },
         Op_EncodeISOArray,
         { { 2, ShenandoahLoad },                  { 3, ShenandoahStore } },
+        Op_EncodeUtf8FromUtf16,
+        { { 2, ShenandoahLoad },                  { 3, ShenandoahStore } },
+        Op_DecodeUtf8ToUtf16,
+        { { 2, ShenandoahLoad },                  { 3, ShenandoahStore } },
         Op_CountPositives,
         { { 2, ShenandoahLoad },                  { -1, ShenandoahNone} },
         Op_CastP2X,
diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
index eb2843008..3b3e8c281 100644
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -1024,6 +1024,8 @@
   static_field(VM_Version, _zva_length, int)                            \
   static_field(StubRoutines::aarch64, _count_positives, address)        \
   static_field(StubRoutines::aarch64, _count_positives_long, address)   \
+  static_field(StubRoutines::aarch64, _convert_masked_utf8_to_utf16, address) \
+  static_field(StubRoutines::aarch64, _scalar_convert_utf8_to_utf16, address) \
   static_field(VM_Version, _rop_protection, bool)                       \
   volatile_nonstatic_field(JavaFrameAnchor, _last_Java_fp, intptr_t*)
 
diff --git a/src/hotspot/share/legal/simdutf.md b/src/hotspot/share/legal/simdutf.md
new file mode 100644
index 000000000..f74e1b09e
--- /dev/null
+++ b/src/hotspot/share/legal/simdutf.md
@@ -0,0 +1,237 @@
+## simdutf
+
+### Notice
+Portions of the HotSpot AArch64 UTF conversion implementation, including the
+lookup tables in `src/hotspot/cpu/aarch64/simdutf_utf_tables.hpp`, are derived
+from the simdutf project.
+
+simdutf is dual-licensed under the Apache License 2.0 and the MIT License.
+
+### Apache License 2.0
+```text
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute
+       must include a readable copy of the attribution notices
+       contained within such NOTICE file, excluding those notices
+       that do not pertain to any part of the Derivative Works, in
+       at least one of the following places: within a NOTICE text
+       file distributed as part of the Derivative Works; within the
+       Source form or documentation, if provided along with the
+       Derivative Works; or, within a display generated by the
+       Derivative Works, if and wherever such third-party notices
+       normally appear. The contents of the NOTICE file are for
+       informational purposes only and do not modify the License.
+       You may add Your own attribution notices within Derivative
+       Works that You distribute, alongside or as an addendum to the
+       NOTICE text from the Work, provided that such additional
+       attribution notices cannot be construed as modifying the
+       License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "{}"
+   replaced with your own identifying information. (Don't include
+   the brackets!) The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright 2020 The simdutf authors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```
+
+### MIT License
+```text
+Copyright 2021 The simdutf authors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```
diff --git a/src/hotspot/share/opto/c2compiler.cpp b/src/hotspot/share/opto/c2compiler.cpp
index 0c642211e..f924e7800 100644
--- a/src/hotspot/share/opto/c2compiler.cpp
+++ b/src/hotspot/share/opto/c2compiler.cpp
@@ -281,6 +281,12 @@ bool C2Compiler::is_intrinsic_supported(vmIntrinsics::ID id) {
   case vmIntrinsics::_encodeByteISOArray:
     if (!Matcher::match_rule_supported(Op_EncodeISOArray)) return false;
     break;
+  case vmIntrinsics::_encodeUtf8FromUtf16:
+    if (!Matcher::match_rule_supported(Op_EncodeUtf8FromUtf16)) return false;
+    break;
+  case vmIntrinsics::_decodeUtf8ToUtf16:
+    if (!Matcher::match_rule_supported(Op_DecodeUtf8ToUtf16)) return false;
+    break;
   case vmIntrinsics::_countPositives:
     if (!Matcher::match_rule_supported(Op_CountPositives))  return false;
     break;
diff --git a/src/hotspot/share/opto/classes.hpp b/src/hotspot/share/opto/classes.hpp
index bc259eed2..6ae154ab7 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -169,6 +169,7 @@ macro(CountTrailingZerosV)
 macro(CreateEx)
 macro(DecodeN)
 macro(DecodeNKlass)
+macro(DecodeUtf8ToUtf16)
 macro(DivHF)
 macro(DivD)
 macro(DivF)
@@ -184,6 +185,7 @@ macro(UDivModL)
 macro(EncodeISOArray)
 macro(EncodeP)
 macro(EncodePKlass)
+macro(EncodeUtf8FromUtf16)
 macro(FastLock)
 macro(FastUnlock)
 macro(FmaD)
diff --git a/src/hotspot/share/opto/escape.cpp b/src/hotspot/share/opto/escape.cpp
index 3dd43f12b..6ad31f15f 100644
--- a/src/hotspot/share/opto/escape.cpp
+++ b/src/hotspot/share/opto/escape.cpp
@@ -1679,7 +1679,9 @@ void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *de
     case Op_StrInflatedCopy:
     case Op_StrCompressedCopy:
     case Op_VectorizedHashCode:
-    case Op_EncodeISOArray: {
+    case Op_EncodeISOArray:
+    case Op_DecodeUtf8ToUtf16:
+    case Op_EncodeUtf8FromUtf16: {
       add_local_var(n, PointsToNode::ArgEscape);
       delayed_worklist->push(n); // Process it later.
       break;
@@ -1835,7 +1837,9 @@ void ConnectionGraph::add_final_edges(Node *n) {
     case Op_StrIndexOfChar:
     case Op_StrInflatedCopy:
     case Op_StrCompressedCopy:
-    case Op_EncodeISOArray: {
+    case Op_EncodeISOArray:
+    case Op_DecodeUtf8ToUtf16:
+    case Op_EncodeUtf8FromUtf16: {
       // char[]/byte[] arrays passed to string intrinsic do not escape but
       // they are not scalar replaceable. Adjust escape state for them.
       // Start from in(2) edge since in(1) is memory edge.
@@ -4193,8 +4197,8 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
       if (mem->is_LoadStore()) {
         adr = mem->in(MemNode::Address);
       } else {
-        assert(mem->Opcode() == Op_EncodeISOArray ||
-               mem->Opcode() == Op_StrCompressedCopy, "sanity");
+        assert(mem->Opcode() == Op_EncodeISOArray || mem->Opcode() == Op_EncodeUtf8FromUtf16 ||
+               mem->Opcode() == Op_DecodeUtf8ToUtf16 || mem->Opcode() == Op_StrCompressedCopy, "sanity");
         adr = mem->in(3); // Memory edge corresponds to destination array
       }
       const Type *at = igvn->type(adr);
@@ -4606,6 +4610,16 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist,
           // EncodeISOArray overwrites destination array
           memnode_worklist.append_if_missing(use);
         }
+      } else if (use->Opcode() == Op_DecodeUtf8ToUtf16) {
+        if (use->in(MemNode::Memory) == n || use->in(3) == n) {
+          // DecodeUtf8ToUtf16 overwrites destination array
+          memnode_worklist.append_if_missing(use);
+        }
+      } else if (use->Opcode() == Op_EncodeUtf8FromUtf16) {
+        if (use->in(MemNode::Memory) == n || use->in(3) == n) {
+          // EncodeUtf8FromUtf16 overwrites destination array
+          memnode_worklist.append_if_missing(use);
+        }
       } else {
         uint op = use->Opcode();
         if ((op == Op_StrCompressedCopy || op == Op_StrInflatedCopy) &&
@@ -4719,7 +4733,8 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist,
       // Check direct uses of StrInflatedCopy.
       // It is memory type Node - no special SCMemProj node.
     } else if (n->Opcode() == Op_StrCompressedCopy ||
-               n->Opcode() == Op_EncodeISOArray) {
+               n->Opcode() == Op_EncodeISOArray || n->Opcode() == Op_EncodeUtf8FromUtf16 ||
+               n->Opcode() == Op_DecodeUtf8ToUtf16) {
       // get the memory projection
       n = n->find_out_with(Op_SCMemProj);
       assert(n != nullptr && n->Opcode() == Op_SCMemProj, "memory projection required");
@@ -4776,6 +4791,16 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist,
           // EncodeISOArray overwrites destination array
           memnode_worklist.append_if_missing(use);
         }
+      } else if (use->Opcode() == Op_DecodeUtf8ToUtf16) {
+        if (use->in(MemNode::Memory) == n || use->in(3) == n) {
+          // DecodeUtf8ToUtf16 overwrites destination array
+          memnode_worklist.append_if_missing(use);
+        }
+      } else if (use->Opcode() == Op_EncodeUtf8FromUtf16) {
+        if (use->in(MemNode::Memory) == n || use->in(3) == n) {
+          // EncodeUtf8FromUtf16 overwrites destination array
+          memnode_worklist.append_if_missing(use);
+        }
       } else {
         uint op = use->Opcode();
         if ((use->in(MemNode::Memory) == n) &&
diff --git a/src/hotspot/share/opto/intrinsicnode.cpp b/src/hotspot/share/opto/intrinsicnode.cpp
index e67352d85..154bbf2e7 100644
--- a/src/hotspot/share/opto/intrinsicnode.cpp
+++ b/src/hotspot/share/opto/intrinsicnode.cpp
@@ -117,6 +117,46 @@ const Type* EncodeISOArrayNode::Value(PhaseGVN* phase) const {
   return bottom_type();
 }
 
+//=============================================================================
+//------------------------------match_edge-------------------------------------
+// Do not match memory edge
+uint EncodeUtf8FromUtf16Node::match_edge(uint idx) const {
+  return idx == 2 || idx == 3; // EncodeUtf8FromUtf16 src (Binary dst len)
+}
+
+//------------------------------Ideal------------------------------------------
+// Return a node which is more "ideal" than the current node.  Strip out
+// control copies
+Node* EncodeUtf8FromUtf16Node::Ideal(PhaseGVN* phase, bool can_reshape) {
+  return remove_dead_region(phase, can_reshape) ? this : nullptr;
+}
+
+//------------------------------Value------------------------------------------
+const Type* EncodeUtf8FromUtf16Node::Value(PhaseGVN* phase) const {
+  if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP;
+  return bottom_type();
+}
+
+//=============================================================================
+//------------------------------match_edge-------------------------------------
+// Do not match memory edge
+uint DecodeUtf8ToUtf16Node::match_edge(uint idx) const {
+  return idx == 2 || idx == 3; // DecodeUtf8ToUtf16 src (Binary dst len)
+}
+
+//------------------------------Ideal------------------------------------------
+// Return a node which is more "ideal" than the current node.  Strip out
+// control copies
+Node* DecodeUtf8ToUtf16Node::Ideal(PhaseGVN* phase, bool can_reshape) {
+  return remove_dead_region(phase, can_reshape) ? this : nullptr;
+}
+
+//------------------------------Value------------------------------------------
+const Type* DecodeUtf8ToUtf16Node::Value(PhaseGVN* phase) const {
+  if (in(0) && phase->type(in(0)) == Type::TOP) return Type::TOP;
+  return bottom_type();
+}
+
 //------------------------------CopySign-----------------------------------------
 CopySignDNode* CopySignDNode::make(PhaseGVN& gvn, Node* in1, Node* in2) {
   return new CopySignDNode(in1, in2, gvn.makecon(TypeD::ZERO));
diff --git a/src/hotspot/share/opto/intrinsicnode.hpp b/src/hotspot/share/opto/intrinsicnode.hpp
index 3c204f88b..ce27eec08 100644
--- a/src/hotspot/share/opto/intrinsicnode.hpp
+++ b/src/hotspot/share/opto/intrinsicnode.hpp
@@ -205,6 +205,40 @@ class EncodeISOArrayNode: public Node {
   }
 };
 
+//------------------------------EncodeUtf8FromUtf16Node-----------------------
+// encode char[] to byte[] in UTF8
+class EncodeUtf8FromUtf16Node: public Node {
+ public:
+  EncodeUtf8FromUtf16Node(Node* control, Node* arymem, Node* s1, Node* s2, Node* c)
+    : Node(control, arymem, s1, s2, c) {}
+
+  virtual int Opcode() const;
+  virtual bool depends_only_on_test() const { return false; }
+  virtual const Type* bottom_type() const { return TypeInt::INT; }
+  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
+  virtual uint match_edge(uint idx) const;
+  virtual uint ideal_reg() const { return Op_RegI; }
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+  virtual const Type* Value(PhaseGVN* phase) const;
+};
+
+//------------------------------DecodeUtf8ToUtf16Node-------------------------
+// decode byte[] in UTF8 to char[] in UTF16
+class DecodeUtf8ToUtf16Node: public Node {
+ public:
+  DecodeUtf8ToUtf16Node(Node* control, Node* arymem, Node* s1, Node* s2, Node* c)
+    : Node(control, arymem, s1, s2, c) {}
+
+  virtual int Opcode() const;
+  virtual bool depends_only_on_test() const { return false; }
+  virtual const Type* bottom_type() const { return TypeInt::INT; }
+  virtual const TypePtr* adr_type() const { return TypePtr::BOTTOM; }
+  virtual uint match_edge(uint idx) const;
+  virtual uint ideal_reg() const { return Op_RegI; }
+  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
+  virtual const Type* Value(PhaseGVN* phase) const;
+};
+
 //-------------------------------DigitNode----------------------------------------
 class DigitNode : public Node {
 public:
diff --git a/src/hotspot/share/opto/lcm.cpp b/src/hotspot/share/opto/lcm.cpp
index 4df3bbab7..d4aceb697 100644
--- a/src/hotspot/share/opto/lcm.cpp
+++ b/src/hotspot/share/opto/lcm.cpp
@@ -212,6 +212,8 @@ void PhaseCFG::implicit_null_check(Block* block, Node *proj, Node *val, int allo
     case Op_StrInflatedCopy:
     case Op_StrCompressedCopy:
     case Op_EncodeISOArray:
+    case Op_DecodeUtf8ToUtf16:
+    case Op_EncodeUtf8FromUtf16:
     case Op_CountPositives:
       // Not a legit memory op for implicit null check regardless of
       // embedded loads
diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp
index f74af3838..c4dd6e242 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -666,7 +666,10 @@ bool LibraryCallKit::try_to_inline(int predicate) {
     return inline_encodeISOArray(false);
   case vmIntrinsics::_encodeAsciiArray:
     return inline_encodeISOArray(true);
-
+  case vmIntrinsics::_encodeUtf8FromUtf16:
+    return inline_encodeUtf8FromUtf16();
+  case vmIntrinsics::_decodeUtf8ToUtf16:
+    return inline_decodeUtf8ToUtf16();
   case vmIntrinsics::_updateCRC32:
     return inline_updateCRC32();
   case vmIntrinsics::_updateBytesCRC32:
@@ -6151,6 +6154,101 @@ bool LibraryCallKit::inline_encodeISOArray(bool ascii) {
   return true;
 }
 
+//-------------inline_encodeUtf8FromUtf16-----------------------------------
+// encode char[] to byte[] in UTF8
+bool LibraryCallKit::inline_encodeUtf8FromUtf16() {
+  assert(callee()->signature()->size() == 5, "encodeUtf8FromUtf16 has 5 parameters");
+  // no receiver since it is static method
+  Node* src = argument(0);
+  Node* src_offset = argument(1);
+  Node* dst = argument(2);
+  Node* dst_offset = argument(3);
+  Node* length = argument(4);
+
+  src = must_be_not_null(src, true);
+  dst = must_be_not_null(dst, true);
+
+  const TypeAryPtr* src_type = src->Value(&_gvn)->isa_aryptr();
+  const TypeAryPtr* dst_type = dst->Value(&_gvn)->isa_aryptr();
+  if (src_type == nullptr || src_type->elem() == Type::BOTTOM ||
+      dst_type == nullptr || dst_type->elem() == Type::BOTTOM) {
+    // failed array check
+    return false;
+  }
+
+  // Figure out the size and type of the elements we will be copying.
+  BasicType src_elem = src_type->elem()->array_element_basic_type();
+  BasicType dst_elem = dst_type->elem()->array_element_basic_type();
+  if (!((src_elem == T_CHAR) || (src_elem == T_BYTE)) || dst_elem != T_BYTE) {
+    return false;
+  }
+
+  Node* src_start = array_element_address(src, src_offset, T_CHAR);
+  Node* dst_start = array_element_address(dst, dst_offset, dst_elem);
+  // 'src_start' points to src array + scaled offset
+  // 'dst_start' points to dst array + scaled offset
+
+  const TypeAryPtr* mtype = TypeAryPtr::BYTES;
+  Node* enc = new EncodeUtf8FromUtf16Node(control(), memory(mtype),
+                                          src_start, dst_start, length);
+  enc = _gvn.transform(enc);
+  Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
+  set_memory(res_mem, mtype);
+  set_result(enc);
+  clear_upper_avx();
+
+  return true;
+}
+
+//-------------inline_decodeUtf8ToUtf16-----------------------------------
+// decode byte[] to char[] in UTF16
+bool LibraryCallKit::inline_decodeUtf8ToUtf16() {
+  assert(callee()->signature()->size() == 5, "decodeUtf8ToUtf16 has 5 parameters");
+  // no receiver since it is static method
+  Node* src = argument(0);
+  Node* src_offset = argument(1);
+  Node* dst = argument(2);
+  Node* dst_offset = argument(3);
+  Node* length = argument(4);
+
+  src = must_be_not_null(src, true);
+  dst = must_be_not_null(dst, true);
+
+  Node* new_length = _gvn.transform(new SubINode(length, src_offset));
+
+  const TypeAryPtr* src_type = src->Value(&_gvn)->isa_aryptr();
+  const TypeAryPtr* dst_type = dst->Value(&_gvn)->isa_aryptr();
+  if (src_type == nullptr || src_type->elem() == Type::BOTTOM ||
+      dst_type == nullptr || dst_type->elem() == Type::BOTTOM) {
+    // failed array check
+    return false;
+  }
+
+  // Figure out the size and type of the elements we will be copying.
+  BasicType src_elem = src_type->elem()->array_element_basic_type();
+  BasicType dst_elem = dst_type->elem()->array_element_basic_type();
+  if (!((src_elem == T_CHAR) || (src_elem == T_BYTE)) ||
+      !(dst_elem == T_CHAR || dst_elem == T_BYTE)) {
+    return false;
+  }
+
+  Node* src_start = array_element_address(src, src_offset, src_elem);
+  Node* dst_start = array_element_address(dst, dst_offset, T_CHAR);
+  // 'src_start' points to src array + scaled offset
+  // 'dst_start' points to dst array + scaled offset
+
+  const TypeAryPtr* mtype = TypeAryPtr::BYTES;
+  Node* enc = new DecodeUtf8ToUtf16Node(control(), memory(mtype),
+                                        src_start, dst_start, new_length);
+  enc = _gvn.transform(enc);
+  Node* res_mem = _gvn.transform(new SCMemProjNode(enc));
+  set_memory(res_mem, mtype);
+  set_result(enc);
+  clear_upper_avx();
+
+  return true;
+}
+
 //-------------inline_multiplyToLen-----------------------------------
 bool LibraryCallKit::inline_multiplyToLen() {
   assert(UseMultiplyToLenIntrinsic, "not implemented on this platform");
diff --git a/src/hotspot/share/opto/library_call.hpp b/src/hotspot/share/opto/library_call.hpp
index 1be08df32..3048e97c6 100644
--- a/src/hotspot/share/opto/library_call.hpp
+++ b/src/hotspot/share/opto/library_call.hpp
@@ -341,6 +341,8 @@ class LibraryCallKit : public GraphKit {
   Node* get_block_size_from_digest_object(Node *digestBase_object);
   Node* inline_digestBase_implCompressMB_predicate(int predicate);
   bool inline_encodeISOArray(bool ascii);
+  bool inline_decodeUtf8ToUtf16();
+  bool inline_encodeUtf8FromUtf16();
   bool inline_updateCRC32();
   bool inline_updateBytesCRC32();
   bool inline_updateByteBufferCRC32();
diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp
index 58105afd9..e5622fea7 100644
--- a/src/hotspot/share/opto/loopTransform.cpp
+++ b/src/hotspot/share/opto/loopTransform.cpp
@@ -904,6 +904,8 @@ bool IdealLoopTree::policy_maximally_unroll(PhaseIdealLoop* phase) const {
       case Op_StrIndexOf:
       case Op_StrIndexOfChar:
       case Op_EncodeISOArray:
+      case Op_EncodeUtf8FromUtf16:
+      case Op_DecodeUtf8ToUtf16:
       case Op_AryEq:
       case Op_CountPositives: {
         return false;
@@ -1065,6 +1067,8 @@ bool IdealLoopTree::policy_unroll(PhaseIdealLoop *phase) {
       case Op_StrIndexOf:
       case Op_StrIndexOfChar:
       case Op_EncodeISOArray:
+      case Op_EncodeUtf8FromUtf16:
+      case Op_DecodeUtf8ToUtf16:
       case Op_AryEq:
       case Op_VectorizedHashCode:
       case Op_CountPositives: {
diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp
index 99fedcdf8..7be9f43fa 100644
--- a/src/hotspot/share/opto/macro.cpp
+++ b/src/hotspot/share/opto/macro.cpp
@@ -243,8 +243,8 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me
       if (mem->is_LoadStore()) {
         adr = mem->in(MemNode::Address);
       } else {
-        assert(mem->Opcode() == Op_EncodeISOArray ||
-               mem->Opcode() == Op_StrCompressedCopy, "sanity");
+        assert(mem->Opcode() == Op_EncodeISOArray || mem->Opcode() == Op_EncodeUtf8FromUtf16 ||
+               mem->Opcode() == Op_DecodeUtf8ToUtf16 || mem->Opcode() == Op_StrCompressedCopy, "sanity");
         adr = mem->in(3); // Destination array
       }
       const TypePtr* atype = adr->bottom_type()->is_ptr();
@@ -420,6 +420,8 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
       } else if (val->Opcode() == Op_SCMemProj) {
         assert(val->in(0)->is_LoadStore() ||
                val->in(0)->Opcode() == Op_EncodeISOArray ||
+               val->in(0)->Opcode() == Op_EncodeUtf8FromUtf16 ||
+               val->in(0)->Opcode() == Op_DecodeUtf8ToUtf16 ||
                val->in(0)->Opcode() == Op_StrCompressedCopy, "sanity");
         assert(false, "Object is not scalar replaceable if a LoadStore node accesses its field");
         return nullptr;
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index 0849b40ad..32012823f 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -1113,6 +1113,8 @@ static void match_alias_type(Compile* C, Node* n, Node* m) {
     case Op_StrCompressedCopy:
     case Op_OnSpinWait:
     case Op_EncodeISOArray:
+    case Op_EncodeUtf8FromUtf16:
+    case Op_DecodeUtf8ToUtf16:
       nidx = Compile::AliasIdxTop;
       nat = nullptr;
       break;
@@ -2302,6 +2304,8 @@ bool Matcher::find_shared_visit(MStack& mstack, Node* n, uint opcode, bool& mem_
     case Op_StrInflatedCopy:
     case Op_StrCompressedCopy:
     case Op_EncodeISOArray:
+    case Op_EncodeUtf8FromUtf16:
+    case Op_DecodeUtf8ToUtf16:
     case Op_FmaD:
     case Op_FmaF:
     case Op_FmaHF:
@@ -2468,6 +2472,8 @@ void Matcher::find_shared_post_visit(Node* n, uint opcode) {
       break;
     }
     case Op_EncodeISOArray:
+    case Op_EncodeUtf8FromUtf16:
+    case Op_DecodeUtf8ToUtf16:
     case Op_StrCompressedCopy:
     case Op_StrInflatedCopy: {
       // Restructure into a binary tree for Matching.
diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp
index ebdf69083..f0390aed4 100644
--- a/src/hotspot/share/runtime/threads.cpp
+++ b/src/hotspot/share/runtime/threads.cpp
@@ -353,9 +353,13 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
 
   initialize_class(vmSymbols::java_lang_String(), CHECK);
 
-  // Inject CompactStrings value after the static initializers for String ran.
+  // Inject CompactStrings and UseUTFConversionIntrinsics(AARCH64) value after the static initializers for String ran.
   java_lang_String::set_compact_strings(CompactStrings);
 
+#ifdef AARCH64
+  java_lang_String::set_utf_conversion_intrinsics(UseUTFConversionIntrinsics);
+#endif // AARCH64
+
   // Initialize java_lang.System (needed before creating the thread)
   initialize_class(vmSymbols::java_lang_System(), CHECK);
   // The VM creates & returns objects of this class. Make sure it's initialized.
diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java
index 52af7dfd5..d8d2a71ff 100644
--- a/src/java.base/share/classes/java/lang/String.java
+++ b/src/java.base/share/classes/java/lang/String.java
@@ -227,8 +227,14 @@ public final class String
      */
     static final boolean COMPACT_STRINGS;
 
+    /**
+     * True if UTF Conversion intrinsics are enabled in the VM by -XX:+UseUTFConversionIntrinsics.
+     */
+    private static final boolean UTF_CONVERSION_INTRINSICS;
+
     static {
         COMPACT_STRINGS = true;
+        UTF_CONVERSION_INTRINSICS = false;
     }
 
     /**
@@ -1081,28 +1087,23 @@ public final class String
     }
 
     private static boolean isNotContinuation(int b) {
-        return (b & 0xc0) != 0x80;
+        return StringCoding.isNotContinuation(b);
     }
 
     private static boolean isMalformed3(int b1, int b2, int b3) {
-        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
-                (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
+        return StringCoding.isMalformed3(b1, b2, b3);
     }
 
     private static boolean isMalformed3_2(int b1, int b2) {
-        return (b1 == (byte)0xe0 && (b2 & 0xe0) == 0x80) ||
-                (b2 & 0xc0) != 0x80;
+        return StringCoding.isMalformed3_2(b1, b2);
     }
 
     private static boolean isMalformed4(int b2, int b3, int b4) {
-        return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
-                (b4 & 0xc0) != 0x80;
+        return StringCoding.isMalformed4(b2, b3, b4);
     }
 
     private static boolean isMalformed4_2(int b1, int b2) {
-        return (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
-                (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
-                (b2 & 0xc0) != 0x80;
+        return StringCoding.isMalformed4_2(b1, b2);
     }
 
     private static boolean isMalformed4_3(int b3) {
@@ -1110,32 +1111,30 @@ public final class String
     }
 
     private static char decode2(int b1, int b2) {
-        return (char)(((b1 << 6) ^ b2) ^
-                (((byte) 0xC0 << 6) ^
-                        ((byte) 0x80 << 0)));
+        return StringCoding.decode2(b1, b2);
     }
 
     private static char decode3(int b1, int b2, int b3) {
-        return (char)((b1 << 12) ^
-                (b2 <<  6) ^
-                (b3 ^
-                        (((byte) 0xE0 << 12) ^
-                                ((byte) 0x80 <<  6) ^
-                                ((byte) 0x80 <<  0))));
+        return StringCoding.decode3(b1, b2, b3);
     }
 
     private static int decode4(int b1, int b2, int b3, int b4) {
-        return ((b1 << 18) ^
-                (b2 << 12) ^
-                (b3 <<  6) ^
-                (b4 ^
-                        (((byte) 0xF0 << 18) ^
-                                ((byte) 0x80 << 12) ^
-                                ((byte) 0x80 <<  6) ^
-                                ((byte) 0x80 <<  0))));
+        return StringCoding.decode4(b1, b2, b3, b4);
     }
 
     private static int decodeUTF8_UTF16(byte[] src, int sp, int sl, byte[] dst, int dp, boolean doReplace) {
+        if (UTF_CONVERSION_INTRINSICS) {
+            // 1 attempt to intrinsic solution. If failed -> use std java method
+            int ret = StringCoding.implDecodeUtf8ToUtf16(src, sp, dst, dp, sl);
+            if (ret > 0) {
+                // ret contains dp when OK
+                return ret + dp;
+            }
+        }
+        return decodeUTF8_UTF16SlowPath(src, sp, sl, dst, dp, doReplace);
+    }
+
+    private static int decodeUTF8_UTF16SlowPath(byte[] src, int sp, int sl, byte[] dst, int dp, boolean doReplace) {
         while (sp < sl) {
             int b1 = src[sp++];
             if (b1 >= 0) {
@@ -1322,6 +1321,30 @@ public final class String
     }
 
     private static byte[] encodeUTF8_UTF16(byte[] val, boolean doReplace) {
+        if (!UTF_CONVERSION_INTRINSICS) {
+            return encodeUTF8_UTF16SlowPath(val, doReplace);
+        }
+
+        int len = val.length >> 1;
+
+        if (len < 24) {
+            return encodeUTF8_UTF16SlowPath(val, doReplace);
+        }
+
+        byte[] dst = new byte[len * 3 + 16]; // to avoid overruns on some special cases
+        // 1 attempt to intrinsic solution. If failed -> use std java method
+        int ret = StringCoding.implEncodeUtf8fromUtf16(val, 0, dst, 0, len);
+
+        if (ret <= 0) {
+            return encodeUTF8_UTF16SlowPath(val, doReplace);
+        }
+        if (ret == dst.length) {
+            return dst;
+        }
+        return Arrays.copyOf(dst, ret);
+    }
+
+    private static byte[] encodeUTF8_UTF16SlowPath(byte[] val, boolean doReplace) {
         int dp = 0;
         int sp = 0;
         int sl = val.length >> 1;
diff --git a/src/java.base/share/classes/java/lang/StringCoding.java b/src/java.base/share/classes/java/lang/StringCoding.java
index c02af28c3..cfdc63ccc 100644
--- a/src/java.base/share/classes/java/lang/StringCoding.java
+++ b/src/java.base/share/classes/java/lang/StringCoding.java
@@ -26,6 +26,7 @@
 
 package java.lang;
 
+import jdk.internal.vm.annotation.ForceInline;
 import jdk.internal.vm.annotation.IntrinsicCandidate;
 
 /**
@@ -97,6 +98,65 @@ class StringCoding {
         return len;
     }
 
+    @ForceInline
+    static boolean isNotContinuation(int b) {
+        return (b & 0xc0) != 0x80;
+    }
+
+    @ForceInline
+    static boolean isMalformed3(int b1, int b2, int b3) {
+        return (b1 == (byte) 0xe0 && (b2 & 0xe0) == 0x80) ||
+                (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80;
+    }
+
+    @ForceInline
+    static boolean isMalformed3_2(int b1, int b2) {
+        return (b1 == (byte) 0xe0 && (b2 & 0xe0) == 0x80) ||
+                (b2 & 0xc0) != 0x80;
+    }
+
+    @ForceInline
+    static boolean isMalformed4(int b2, int b3, int b4) {
+        return (b2 & 0xc0) != 0x80 || (b3 & 0xc0) != 0x80 ||
+                (b4 & 0xc0) != 0x80;
+    }
+
+    @ForceInline
+    static boolean isMalformed4_2(int b1, int b2) {
+        return (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
+                (b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
+                (b2 & 0xc0) != 0x80;
+    }
+
+    @ForceInline
+    static char decode2(int b1, int b2) {
+        return (char) (((b1 << 6) ^ b2) ^
+                (((byte) 0xC0 << 6) ^
+                        ((byte) 0x80 << 0)));
+    }
+
+    @ForceInline
+    static char decode3(int b1, int b2, int b3) {
+        return (char) ((b1 << 12) ^
+                (b2 <<  6) ^
+                (b3 ^
+                        (((byte) 0xE0 << 12) ^
+                                ((byte) 0x80 <<  6) ^
+                                ((byte) 0x80 <<  0))));
+    }
+
+    @ForceInline
+    static int decode4(int b1, int b2, int b3, int b4) {
+        return ((b1 << 18) ^
+                (b2 << 12) ^
+                (b3 <<  6) ^
+                (b4 ^
+                        (((byte) 0xF0 << 18) ^
+                                ((byte) 0x80 << 12) ^
+                                ((byte) 0x80 <<  6) ^
+                                ((byte) 0x80 <<  0))));
+    }
+
     @IntrinsicCandidate
     public static int implEncodeISOArray(byte[] sa, int sp,
                                          byte[] da, int dp, int len) {
@@ -105,23 +165,152 @@ class StringCoding {
             char c = StringUTF16.getChar(sa, sp++);
             if (c > '\u00FF')
                 break;
-            da[dp++] = (byte)c;
+            da[dp++] = (byte) c;
         }
         return i;
     }
 
     @IntrinsicCandidate
     public static int implEncodeAsciiArray(char[] sa, int sp,
-                                           byte[] da, int dp, int len)
-    {
+                                           byte[] da, int dp, int len) {
         int i = 0;
         for (; i < len; i++) {
             char c = sa[sp++];
             if (c >= '\u0080')
                 break;
-            da[dp++] = (byte)c;
+            da[dp++] = (byte) c;
         }
         return i;
     }
 
+    @IntrinsicCandidate
+    public static int implEncodeUtf8fromUtf16(byte[] sa, int sp, byte[] da, int dp, int sl) {
+        while (sp < sl) {
+            // ascii fast loop
+            char c = StringUTF16.getChar(sa, sp);
+            if (c >= '\u0080') {
+                break;
+            }
+            da[dp++] = (byte) c;
+            sp++;
+        }
+        while (sp < sl) {
+            char c = StringUTF16.getChar(sa, sp++);
+            if (c < 0x80) {
+                da[dp++] = (byte) c;
+            } else if (c < 0x800) {
+                da[dp++] = (byte) (0xc0 | (c >> 6));
+                da[dp++] = (byte) (0x80 | (c & 0x3f));
+            } else if (Character.isSurrogate(c)) {
+                int uc = -1;
+                char c2;
+                if (Character.isHighSurrogate(c) && sp < sl &&
+                        Character.isLowSurrogate(c2 = StringUTF16.getChar(sa, sp))) {
+                    uc = Character.toCodePoint(c, c2);
+                }
+                if (uc < 0) {
+                    return -(sp - 1); // in case of unmappable, return index of unmappable as negative value
+                } else {
+                    da[dp++] = (byte) (0xf0 | (uc >> 18));
+                    da[dp++] = (byte) (0x80 | ((uc >> 12) & 0x3f));
+                    da[dp++] = (byte) (0x80 | ((uc >>  6) & 0x3f));
+                    da[dp++] = (byte) (0x80 | (uc & 0x3f));
+                    sp++; // 2 chars
+                }
+            } else {
+                // 3 bytes, 16 bits
+                da[dp++] = (byte) (0xe0 | (c >> 12));
+                da[dp++] = (byte) (0x80 | ((c >>  6) & 0x3f));
+                da[dp++] = (byte) (0x80 | (c & 0x3f));
+            }
+        }
+        // if OK - return number of bytes in destination
+        return dp;
+    }
+
+    /**
+     * Processes characters from the source byte array and writes the
+     * decoded result into the destination array.
+     * <p>
+     * The returned value represents the number of characters produced
+     * by this invocation only, independent of the source or destination
+     * offsets.
+     *
+     * @return the number of characters produced by this method,
+     *         or a negative value if an error occurs
+     */
+    @IntrinsicCandidate
+    public static int implDecodeUtf8ToUtf16(byte[] src, int sp, byte[] dst, int dp, int sl) {
+        int staDp = dp;
+        while (sp < sl) {
+            int b1 = src[sp++];
+            if (b1 >= 0) {
+                StringUTF16.putChar(dst, dp++, (char) b1);
+            } else if ((b1 >> 5) == -2 && (b1 & 0x1e) != 0) {
+                if (sp < sl) {
+                    int b2 = src[sp++];
+                    if (isNotContinuation(b2)) {
+                        // fallback to original path
+                        return -(sp - 1);
+                    } else {
+                        StringUTF16.putChar(dst, dp++, decode2(b1, b2));
+                    }
+                    continue;
+                }
+                // fallback to original path
+                return -(sp);
+            } else if ((b1 >> 4) == -2) {
+                if (sp + 1 < sl) {
+                    int b2 = src[sp++];
+                    int b3 = src[sp++];
+                    if (isMalformed3(b1, b2, b3)) {
+                        // fallback to original path
+                        return -(sp - 3);
+                    } else {
+                        char c = decode3(b1, b2, b3);
+                        if (Character.isSurrogate(c)) {
+                            // fallback to original path
+                            return -(sp - 3);
+                        } else {
+                            StringUTF16.putChar(dst, dp++, c);
+                        }
+                    }
+                    continue;
+                }
+                if (sp < sl && isMalformed3_2(b1, src[sp])) {
+                    // fallback to original path
+                    return -(sp - 1);
+                }
+                // fallback to original path
+                return -(sp - 1);
+            } else if ((b1 >> 3) == -2) {
+                if (sp + 2 < sl) {
+                    int b2 = src[sp++];
+                    int b3 = src[sp++];
+                    int b4 = src[sp++];
+                    int uc = decode4(b1, b2, b3, b4);
+                    if (isMalformed4(b2, b3, b4) ||
+                            !Character.isSupplementaryCodePoint(uc)) { // shortest form check
+                        // fallback to original path
+                        return -(sp - 4);
+                    } else {
+                        StringUTF16.putChar(dst, dp++, Character.highSurrogate(uc));
+                        StringUTF16.putChar(dst, dp++, Character.lowSurrogate(uc));
+                    }
+                    continue;
+                }
+                b1 &= 0xff;
+                if (b1 > 0xf4 || sp < sl && isMalformed4_2(b1, src[sp] & 0xff)) {
+                    // fallback to original path
+                    return -(sp - 1);
+                }
+                // fallback to original path
+                return -(sp - 1);
+            } else {
+                // fallback to original path
+                return -(sp - 1);
+            }
+        }
+        return dp - staDp;
+    }
 }
diff --git a/test/jdk/sun/nio/cs/TestStringCodingUTF8Intrinsics.java b/test/jdk/sun/nio/cs/TestStringCodingUTF8Intrinsics.java
new file mode 100644
index 000000000..840b02845
--- /dev/null
+++ b/test/jdk/sun/nio/cs/TestStringCodingUTF8Intrinsics.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2026, Huawei Technologies Co., Ltd. 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.
+ */
+
+/* @test
+ * @summary Targeted UTF-8 StringCoding coverage for AArch64 UTF conversion intrinsics
+ * @requires os.arch == "aarch64"
+ * @run main/othervm/timeout=2000 -Xbatch -XX:-TieredCompilation -XX:+UseUTFConversionIntrinsics TestStringCodingUTF8Intrinsics
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.CoderResult;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+public class TestStringCodingUTF8Intrinsics {
+    private static final int ITERATIONS = 20_000;
+
+    public static void main(String[] args) throws Exception {
+        testEncodeAscii();
+        testEncodeByte1_2();
+        testEncodeByte1_3();
+        testEncodeScalarFallback();
+        testEncodeIllegalSurrogateFallsBack();
+        testEncodeBoundaryCodePoints();
+        testEncodeThresholdLengths();
+        testEncodeDanglingHighSurrogateAtEnd();
+
+        testDecodeAscii();
+        testDecodeTwoByteSequence();
+        testDecodeThreeByteSequence();
+        testDecodeMixedSequences1_2();
+        testDecodeMixedSequences1_3();
+        testDecodeMixedSequences1_4();
+        testDecodeIllegalUtf8FallsBack();
+        testDecodeBoundaryCodePoints();
+        testDecodeTruncatedUtf8FallsBackToStd();
+        testDecodeSplitLeadingAndContinuationRuns();
+    }
+
+    private static void testEncodeAscii() throws Exception {
+        String s = repeat("ASCII-fast-path-0123456789-", 4);
+        assertEncodeCase("encode-ascii-fast-path", s);
+    }
+
+    private static void testEncodeByte1_2() throws Exception {
+        String s = repeat("Az\u00A2\u07FF", 12);
+        assertEncodeCase("encode-1-2-byte-fast-path", s);
+    }
+
+    private static void testEncodeByte1_3() throws Exception {
+        String s = repeat("A\u00E9\u4F60\u0800", 10);
+        assertEncodeCase("encode-1-3-byte-fast-path", s);
+    }
+
+    private static void testEncodeScalarFallback() throws Exception {
+        String s = repeat("A\u4F60", 6) + "\uD83D\uDE00" + repeat("B\u07FF", 5) + "\uD83D\uDE80Z";
+        assertEncodeCase("encode-scalar-fallback-supplementary-tail", s);
+    }
+
+    private static void testEncodeIllegalSurrogateFallsBack() throws Exception {
+        String s = repeat("A\u4F60", 6) + '\uD800' + repeat("B\u00E9", 8) + '\uDC00';
+        assertEncodeCase("encode-illegal-surrogate-fallback", s);
+    }
+
+    private static void testEncodeBoundaryCodePoints() throws Exception {
+        String s = repeat("\u0000\u007F\u0080\u07FF\u0800\uFFFF", 8)
+                + "\uD800\uDC00"
+                + "\uDBFF\uDFFF";
+        assertEncodeCase("encode-boundary-code-points", s);
+    }
+
+    private static void testEncodeThresholdLengths() throws Exception {
+        assertEncodeCase("encode-threshold-len-7", repeat("A\u00A2\u4F60", 2) + "Z");
+        assertEncodeCase("encode-threshold-len-8", repeat("A\u00A2\u4F60", 2) + "ZW");
+        assertEncodeCase("encode-threshold-len-23", repeat("A\u00A2\u4F60", 7) + "YZ");
+        assertEncodeCase("encode-threshold-len-24", repeat("A\u00A2\u4F60", 8));
+    }
+
+    private static void testEncodeDanglingHighSurrogateAtEnd() throws Exception {
+        String s = repeat("A\u00A2\u4F60", 8) + '\uD83D';
+        assertEncodeCase("encode-dangling-high-surrogate-at-end", s);
+    }
+
+    private static void testDecodeAscii() throws Exception {
+        byte[] bytes = asciiBytes(repeat("ASCII-decode-fast-path-0123456789-", 4));
+        assertDecodeCase("decode-ascii-fast-path", bytes);
+    }
+
+    private static void testDecodeTwoByteSequence() throws Exception {
+        byte[] bytes = utf8Bytes(repeat("\u00A2\u07FF", 16));
+        assertDecodeCase("decode-2-byte-sequence", bytes);
+    }
+
+    private static void testDecodeThreeByteSequence() throws Exception {
+        byte[] bytes = utf8Bytes(repeat("\u4F60\u0800\u20AC", 12));
+        assertDecodeCase("decode-3-byte-sequence", bytes);
+    }
+
+    private static void testDecodeMixedSequences1_2() throws Exception {
+        String s = repeat("A\u00A2B\u07FF", 16);
+        byte[] bytes = utf8Bytes(s);
+        assertDecodeCase("decode-mixed-1-2-byte", bytes);
+    }
+
+    private static void testDecodeMixedSequences1_3() throws Exception {
+        String s = repeat("A\u00A2\u4F60B\u07FFC\u20AC", 12);
+        byte[] bytes = utf8Bytes(s);
+        assertDecodeCase("decode-mixed-1-3-byte", bytes);
+    }
+
+    private static void testDecodeMixedSequences1_4() throws Exception {
+        String s = repeat("A\u00A2\u4F60", 8) + "\uD83D\uDE00"
+                + repeat("B\u07FF\u20AC", 7) + "\uD83D\uDE80C";
+        byte[] bytes = utf8Bytes(s);
+        assertDecodeCase("decode-mixed-1-4-byte", bytes);
+    }
+
+    private static void testDecodeIllegalUtf8FallsBack() throws Exception {
+        byte[] invalid1 = {
+                'A',
+                (byte) 0xE2, (byte) 0x28, (byte) 0xA1,
+                'B',
+                (byte) 0xF0, (byte) 0x28, (byte) 0x8C, (byte) 0xBC,
+                'C'
+        };
+        byte[] invalid2 = {
+                'X',
+                (byte) 0xC0, (byte) 0xAF,
+                'Y',
+                (byte) 0xE0, (byte) 0x80, (byte) 0xAF,
+                'Z',
+                (byte) 0xF4, (byte) 0x90, (byte) 0x80, (byte) 0x80
+        };
+        byte[] bytes = concat(repeat(invalid1, 6), repeat(invalid2, 5));
+        assertDecodeCase("decode-illegal-utf8-fallback", bytes);
+    }
+
+    private static void testDecodeBoundaryCodePoints() throws Exception {
+        String s = repeat("\u0000\u007F\u0080\u07FF\u0800", 8)
+                + "\uFFFD"
+                + "\uD800\uDC00"
+                + "\uDBFF\uDFFF";
+        assertDecodeCase("decode-boundary-code-points", utf8Bytes(s));
+    }
+
+    private static void testDecodeTruncatedUtf8FallsBackToStd() throws Exception {
+        byte[] bytes = concat(
+                utf8Bytes(repeat("A\u00A2\u4F60", 6)),
+                new byte[] {
+                        (byte) 0xC2,
+                        (byte) 0xE2, (byte) 0x82,
+                        (byte) 0xF0, (byte) 0x9F, (byte) 0x98
+                });
+        assertDecodeCase("decode-truncated-utf8-fallback", bytes);
+    }
+
+    private static void testDecodeSplitLeadingAndContinuationRuns() throws Exception {
+        byte[] bytes = concat(
+                utf8Bytes(repeat("A\u00A2\u4F60", 5)),
+                concat(
+                        new byte[] {
+                                (byte) 0x80, (byte) 0x80, (byte) 0x80,
+                                (byte) 0xC2, (byte) 0xA2,
+                                (byte) 0x80,
+                                (byte) 0xE2, (byte) 0x82, (byte) 0xAC
+                        },
+                        utf8Bytes(repeat("B\uD83D\uDE00C", 4))));
+        assertDecodeCase("decode-split-leading-continuation-runs", bytes);
+    }
+
+    private static void assertEncodeCase(String name, String s) throws Exception {
+        byte[] expected = encodeReference(s);
+        for (int i = 0; i < ITERATIONS; i++) {
+            byte[] actual = s.getBytes(StandardCharsets.UTF_8);
+            if (!Arrays.equals(expected, actual)) {
+                failEncode(name, s, expected, actual);
+            }
+        }
+    }
+
+    private static void assertDecodeCase(String name, byte[] bytes) throws Exception {
+        String expected = decodeReference(bytes);
+        for (int i = 0; i < ITERATIONS; i++) {
+            String actual = new String(bytes, StandardCharsets.UTF_8);
+            if (!expected.equals(actual)) {
+                failDecode(name, bytes, expected, actual);
+            }
+        }
+    }
+
+    private static byte[] encodeReference(String s) throws Exception {
+        CharsetEncoder encoder = StandardCharsets.UTF_8.newEncoder();
+        encoder.onMalformedInput(CodingErrorAction.REPLACE)
+               .onUnmappableCharacter(CodingErrorAction.REPLACE)
+               .reset();
+        CharBuffer in = CharBuffer.wrap(s);
+        byte[] out = new byte[(int) (s.length() * encoder.maxBytesPerChar()) + 8];
+        ByteBuffer bb = ByteBuffer.wrap(out);
+        CoderResult cr = encoder.encode(in, bb, true);
+        if (!cr.isUnderflow()) {
+            cr.throwException();
+        }
+        cr = encoder.flush(bb);
+        if (!cr.isUnderflow()) {
+            cr.throwException();
+        }
+        return Arrays.copyOf(out, bb.position());
+    }
+
+    private static String decodeReference(byte[] bytes) throws Exception {
+        CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
+        decoder.onMalformedInput(CodingErrorAction.REPLACE)
+               .onUnmappableCharacter(CodingErrorAction.REPLACE)
+               .reset();
+        ByteBuffer in = ByteBuffer.wrap(bytes);
+        char[] out = new char[(int) (bytes.length * decoder.maxCharsPerByte()) + 8];
+        CharBuffer cb = CharBuffer.wrap(out);
+        CoderResult cr = decoder.decode(in, cb, true);
+        if (!cr.isUnderflow()) {
+            cr.throwException();
+        }
+        cr = decoder.flush(cb);
+        if (!cr.isUnderflow()) {
+            cr.throwException();
+        }
+        return new String(out, 0, cb.position());
+    }
+
+    private static byte[] asciiBytes(String s) {
+        return s.getBytes(StandardCharsets.ISO_8859_1);
+    }
+
+    private static byte[] utf8Bytes(String s) {
+        return s.getBytes(StandardCharsets.UTF_8);
+    }
+
+    private static byte[] concat(byte[] left, byte[] right) {
+        byte[] out = Arrays.copyOf(left, left.length + right.length);
+        System.arraycopy(right, 0, out, left.length, right.length);
+        return out;
+    }
+
+    private static byte[] repeat(byte[] block, int count) {
+        byte[] out = new byte[block.length * count];
+        for (int i = 0; i < count; i++) {
+            System.arraycopy(block, 0, out, i * block.length, block.length);
+        }
+        return out;
+    }
+
+    private static String repeat(String block, int count) {
+        StringBuilder sb = new StringBuilder(block.length() * count);
+        for (int i = 0; i < count; i++) {
+            sb.append(block);
+        }
+        return sb.toString();
+    }
+
+    private static void failEncode(String name, String input, byte[] expected, byte[] actual) {
+        throw new RuntimeException(name
+                + " failed, input length=" + input.length()
+                + ", expected bytes=" + expected.length
+                + ", actual bytes=" + actual.length
+                + ", expected=" + Arrays.toString(expected)
+                + ", actual=" + Arrays.toString(actual));
+    }
+
+    private static void failDecode(String name, byte[] input, String expected, String actual) {
+        throw new RuntimeException(name
+                + " failed, input bytes=" + Arrays.toString(input)
+                + ", expected=\"" + printable(expected) + "\""
+                + ", actual=\"" + printable(actual) + "\"");
+    }
+
+    private static String printable(String s) {
+        StringBuilder sb = new StringBuilder(s.length() * 6);
+        for (int i = 0; i < s.length(); i++) {
+            sb.append(String.format("\\u%04X", (int) s.charAt(i)));
+        }
+        return sb.toString();
+    }
+}
diff --git a/test/micro/org/openjdk/bench/java/lang/StringCodingUTF8Intrinsics.java b/test/micro/org/openjdk/bench/java/lang/StringCodingUTF8Intrinsics.java
new file mode 100644
index 000000000..1bf513e6f
--- /dev/null
+++ b/test/micro/org/openjdk/bench/java/lang/StringCodingUTF8Intrinsics.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2026, Huawei Technologies Co., Ltd. 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.
+ */
+
+package org.openjdk.bench.java.lang;
+
+import org.openjdk.jmh.annotations.*;
+
+@BenchmarkMode(Mode.AverageTime)
+@Warmup(iterations = 3)
+@Measurement(iterations = 5, time = 5)
+@Threads(1)
+public class StringCodingUTF8Intrinsics {
+
+    private static int count = 100000;
+
+    private static byte[][] ss = {
+            "dqwqdwqwqdw".getBytes(),
+            "了这篇文章:".getBytes(),
+            "[  ]hzzone:也就垄断平台总部工资跟老人退休金涨其他收入大多下跌或失业归零(2026-02-06 07:20)\n".getBytes(),
+            "[-5]voTvo:前提就说错了,收入越来越低好吗(2026-02-06 10:16)\n".getBytes(),
+            "[-5]shocker:财富集中和宏大叙事,和万千普通家庭感受相矛盾。(2026-02-06 10:22)\n".getBytes(),
+            "[-5]yourcarin0:预制菜事件忘了?(2026-02-06 11:14)\n".getBytes(),
+            "[+5]whatswrong:单次单人费用涨了,下馆子频率大幅降低(2026-02-06 14:13)".getBytes()
+    };
+
+    @Benchmark
+    public static void TT() {
+        for (int i = 0; i < count; i++) {
+            for (int j = 0; j < ss.length; j++) {
+                String s = new String(ss[j]);
+                byte[] df = s.getBytes();
+                df[df.length - 1] = df[df.length - 2];
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        count = 1;
+        TT();
+    }
+}
-- 
2.33.0