From f8cb04b9ff5b99c95783429601642fa8947270f2 Mon Sep 17 00:00:00 2001
Date: Sat, 16 May 2026 11:39:36 +0800
Subject: Add UTF Conversion Intrinsics for aarch64

---
 src/hotspot/cpu/aarch64/aarch64.ad            |   49 +
 src/hotspot/cpu/aarch64/globals_aarch64.hpp   |    2 +
 .../cpu/aarch64/macroAssembler_aarch64.cpp    |  675 +++++++
 .../cpu/aarch64/macroAssembler_aarch64.hpp    |   16 +
 .../cpu/aarch64/simdutf_utf_tables.hpp        | 1602 +++++++++++++++++
 .../cpu/aarch64/stubGenerator_aarch64.cpp     |  607 +++++++
 .../cpu/aarch64/stubRoutines_aarch64.cpp      |   14 +-
 .../cpu/aarch64/stubRoutines_aarch64.hpp      |   24 +
 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       |   97 +-
 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 |  191 ++
 .../cs/TestStringCodingUTF8Intrinsics.java    |  307 ++++
 .../java/lang/StringCodingUTF8Intrinsics.java |   66 +
 33 files changed, 4113 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/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index 14f81578c..3ad7bb1ef 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -17531,6 +17531,55 @@ instruct expandBitsL_memcon(iRegINoSp dst, memory8 mem, immL mask,
   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_V8 vtmp8,
+                          vRegD_V9 vtmp9, iRegI_R0 result, rFlagsReg cr)
+%{
+  match(Set result (EncodeUtf8FromUtf16 src (Binary dst len)));
+  effect(USE_KILL src, USE_KILL dst, USE_KILL len, KILL vtmp0, KILL vtmp1,
+        KILL vtmp2, KILL vtmp3, KILL vtmp4, KILL vtmp5, KILL vtmp6, KILL vtmp7, KILL vtmp8, KILL 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_V8 vtmp8,
+                          vRegD_V9 vtmp9, vRegD_V10 vtmp10, iRegI_R0 result, rFlagsReg cr)
+%{
+  match(Set result (DecodeUtf8ToUtf16 src (Binary dst len)));
+  effect(USE_KILL src, USE_KILL dst, USE_KILL len, KILL vtmp0, KILL vtmp1, KILL vtmp2, KILL vtmp3,
+        KILL vtmp4, KILL vtmp5, KILL vtmp6, KILL vtmp7, KILL vtmp8, KILL vtmp9, KILL 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 ddc113857..6ea0c9834 100644
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
@@ -219,6 +219,8 @@ define_pd_global(intx, InlineSmallCode,          1000);
           "including prefix=<id> and div=<N>.")                         \
   product(bool, UseStlrForRelease, false,                               \
           "Use stlr instead of dmb ish + str for release stores")       \
+  product(bool, UseUTFConversionIntrinsics, false,                      \
+          "Use Intrinsics for conversion between UTF8 and UTF16")       \
 
 // end of ARCH_FLAGS
 
diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
index d9d43465e..fb43d1ea8 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
@@ -6080,6 +6080,681 @@ 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 74422139d..0eb283b44 100644
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp
@@ -1474,6 +1474,22 @@ 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 fast_log(FloatRegister vtmp0, FloatRegister vtmp1, FloatRegister vtmp2,
                 FloatRegister vtmp3, FloatRegister vtmp4, FloatRegister vtmp5,
                 FloatRegister tmpC1, FloatRegister tmpC2, FloatRegister tmpC3,
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/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
index 2bfc49d05..b304104d2 100644
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp
@@ -5619,6 +5619,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);
     StubCodeMark mark(this, "StubRoutines", isCos ? "libmDcos" : "libmDsin");
@@ -8781,6 +9384,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 c107e614b..8984171ed 100644
--- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.cpp
@@ -1,4 +1,4 @@
-/*
+/*
  * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -62,15 +62,21 @@ address StubRoutines::aarch64::_string_indexof_linear_uu = nullptr;
 address StubRoutines::aarch64::_string_indexof_linear_ul = nullptr;
 address StubRoutines::aarch64::_large_byte_array_inflate = nullptr;
 address StubRoutines::aarch64::_method_entry_barrier = nullptr;
+address StubRoutines::aarch64::_convert_masked_utf8_to_utf16 = NULL;
+address StubRoutines::aarch64::_scalar_convert_utf8_to_utf16 = NULL;
 
 static void empty_spin_wait() { }
 address StubRoutines::aarch64::_spin_wait = CAST_FROM_FN_PTR(address, empty_spin_wait);
 
 bool StubRoutines::aarch64::_completed = false;
 
-/**
- *  crc_table[] from jdk/src/share/native/java/util/zip/zlib-1.2.5/crc32.h
- */
+
+// 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(4096) juint StubRoutines::aarch64::_crc_table[] =
 {
     // Table 0
diff --git a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
index dcc2604ed..26e0bd71e 100644
--- a/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/stubRoutines_aarch64.hpp
@@ -87,11 +87,23 @@ class aarch64 {
   static address _count_positives;
   static address _count_positives_long;
 
+  static address _convert_masked_utf8_to_utf16;
+  static address _scalar_convert_utf8_to_utf16;
   static address get_previous_sp_entry()
   {
     return _get_previous_sp_entry;
   }
 
+  static address scalar_convert_utf8_to_utf16()
+  {
+    return _scalar_convert_utf8_to_utf16;
+  }
+
+  static address convert_masked_utf8_to_utf16()
+  {
+    return _convert_masked_utf8_to_utf16;
+  }
+
   static address f2i_fixup()
   {
     return _f2i_fixup;
@@ -211,6 +223,14 @@ class aarch64 {
     return _spin_wait;
   }
 
+  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;
   }
@@ -228,6 +248,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 be4ee3a3a..b4a7c11e0 100644
--- a/src/hotspot/share/adlc/formssel.cpp
+++ b/src/hotspot/share/adlc/formssel.cpp
@@ -905,7 +905,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 0d7adfc2b..bae1fc9e7 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -262,6 +262,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 e19556cec..b25429d98 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -101,6 +101,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 578b171a5..28bf169a0 100644
--- a/src/hotspot/share/classfile/vmIntrinsics.cpp
+++ b/src/hotspot/share/classfile/vmIntrinsics.cpp
@@ -543,6 +543,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 15ad554d8..7b11494c1 100644
--- a/src/hotspot/share/classfile/vmIntrinsics.hpp
+++ b/src/hotspot/share/classfile/vmIntrinsics.hpp
@@ -425,6 +425,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 2e8b021b4..bffffcaad 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -470,6 +470,7 @@
   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 345f73248..49dbf4380 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -567,6 +567,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 add524d92..ba26c6203 100644
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -859,6 +859,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 9e27ff17d..4d883a370 100644
--- a/src/hotspot/share/opto/c2compiler.cpp
+++ b/src/hotspot/share/opto/c2compiler.cpp
@@ -230,6 +230,12 @@ bool C2Compiler::is_intrinsic_supported(const methodHandle& method) {
   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 892ccc6b8..492a92883 100644
--- a/src/hotspot/share/opto/classes.hpp
+++ b/src/hotspot/share/opto/classes.hpp
@@ -166,6 +166,7 @@ macro(CountTrailingZerosV)
 macro(CreateEx)
 macro(DecodeN)
 macro(DecodeNKlass)
+macro(DecodeUtf8ToUtf16)
 macro(DivD)
 macro(DivF)
 macro(DivI)
@@ -180,6 +181,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 2da6c84df..eaa71081b 100644
--- a/src/hotspot/share/opto/escape.cpp
+++ b/src/hotspot/share/opto/escape.cpp
@@ -667,7 +667,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;
@@ -822,7 +824,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.
@@ -3067,8 +3071,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);
@@ -3457,6 +3461,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) &&
@@ -3543,7 +3557,8 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist,
         continue;
       }
     } 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");
@@ -3598,6 +3613,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 7d8894c8b..103e39006 100644
--- a/src/hotspot/share/opto/intrinsicnode.cpp
+++ b/src/hotspot/share/opto/intrinsicnode.cpp
@@ -118,6 +118,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 e8ebad788..a1ba34ff2 100644
--- a/src/hotspot/share/opto/intrinsicnode.hpp
+++ b/src/hotspot/share/opto/intrinsicnode.hpp
@@ -200,6 +200,40 @@ class EncodeISOArrayNode: public Node {
   virtual const Type* Value(PhaseGVN* phase) const;
 };
 
+//------------------------------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 648c10474..fb8248c50 100644
--- a/src/hotspot/share/opto/lcm.cpp
+++ b/src/hotspot/share/opto/lcm.cpp
@@ -210,6 +210,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 d4edd74e7..397ec0235 100644
--- a/src/hotspot/share/opto/library_call.cpp
+++ b/src/hotspot/share/opto/library_call.cpp
@@ -639,7 +639,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:
@@ -5732,6 +5735,98 @@ 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 f714625a4..0f382ed66 100644
--- a/src/hotspot/share/opto/library_call.hpp
+++ b/src/hotspot/share/opto/library_call.hpp
@@ -313,6 +313,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 bb9a54919..b547fcd96 100644
--- a/src/hotspot/share/opto/loopTransform.cpp
+++ b/src/hotspot/share/opto/loopTransform.cpp
@@ -853,6 +853,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;
@@ -1017,6 +1019,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 1ffeb4bdc..d6e1b413f 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();
@@ -419,6 +419,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 319cb3cff..b22fa78b2 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -1089,6 +1089,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;
@@ -2267,6 +2269,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_FmaVD:
@@ -2430,6 +2434,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 0edf5e8c3..8c242b3ba 100644
--- a/src/hotspot/share/runtime/threads.cpp
+++ b/src/hotspot/share/runtime/threads.cpp
@@ -349,9 +349,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 5216c9903..6e1005b2f 100644
--- a/src/java.base/share/classes/java/lang/String.java
+++ b/src/java.base/share/classes/java/lang/String.java
@@ -222,8 +222,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;
     }
 
     /**
@@ -1068,28 +1074,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) {
@@ -1097,32 +1098,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) {
@@ -1309,6 +1308,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 293fbdb78..ed7a35434 100644
--- a/src/java.base/share/classes/java/lang/StringCoding.java
+++ b/src/java.base/share/classes/java/lang/StringCoding.java
@@ -25,6 +25,7 @@
 
 package java.lang;
 
+import jdk.internal.vm.annotation.ForceInline;
 import jdk.internal.vm.annotation.IntrinsicCandidate;
 
 /**
@@ -57,6 +58,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) {
@@ -84,4 +144,135 @@ class StringCoding {
         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..cee416ed6
--- /dev/null
+++ b/test/jdk/sun/nio/cs/TestStringCodingUTF8Intrinsics.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @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 {
+        testEncodeAsciiFastPath();
+        testEncodeOneTwoByteFastPath();
+        testEncodeOneThreeByteFastPath();
+        testEncodeBoundaryCodePoints();
+        testEncodeThresholdLengths();
+        testEncodeScalarFallbackForSupplementaryAndTail();
+        testEncodeIllegalSurrogateFallsBackToStd();
+        testEncodeDanglingHighSurrogateAtEnd();
+
+        testDecodeAsciiFastPath();
+        testDecodeTwoByteSequence();
+        testDecodeThreeByteSequence();
+        testDecodeBoundaryCodePoints();
+        testDecodeMixedOneTwoByteSequences();
+        testDecodeMixedOneThreeByteSequences();
+        testDecodeMixedOneFourByteSequences();
+        testDecodeTruncatedUtf8FallsBackToStd();
+        testDecodeSplitLeadingAndContinuationRuns();
+        testDecodeIllegalUtf8FallsBackToStd();
+    }
+
+    private static void testEncodeAsciiFastPath() throws Exception {
+        String s = repeat("ASCII-fast-path-0123456789-", 4);
+        assertEncodeCase("encode-ascii-fast-path", s);
+    }
+
+    private static void testEncodeOneTwoByteFastPath() throws Exception {
+        String s = repeat("Az\u00A2\u07FF", 12);
+        assertEncodeCase("encode-1-2-byte-fast-path", s);
+    }
+
+    private static void testEncodeOneThreeByteFastPath() throws Exception {
+        String s = repeat("A\u00E9\u4F60\u0800", 10);
+        assertEncodeCase("encode-1-3-byte-fast-path", 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 testEncodeScalarFallbackForSupplementaryAndTail() 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 testEncodeIllegalSurrogateFallsBackToStd() throws Exception {
+        String s = repeat("A\u4F60", 6) + '\uD800' + repeat("B\u00E9", 8) + '\uDC00';
+        assertEncodeCase("encode-illegal-surrogate-fallback", s);
+    }
+
+    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 testDecodeAsciiFastPath() 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 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 testDecodeMixedOneTwoByteSequences() throws Exception {
+        String s = repeat("A\u00A2B\u07FF", 16);
+        byte[] bytes = utf8Bytes(s);
+        assertDecodeCase("decode-mixed-1-2-byte", bytes);
+    }
+
+    private static void testDecodeMixedOneThreeByteSequences() 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 testDecodeMixedOneFourByteSequences() 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 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 testDecodeIllegalUtf8FallsBackToStd() 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 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..51a591313
--- /dev/null
+++ b/test/micro/org/openjdk/bench/java/lang/StringCodingUTF8Intrinsics.java
@@ -0,0 +1,66 @@
+/*
+ * 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.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+
+@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(),
+            "\u4e86\u8fd9\u7bc7\u6587\u7ae0\uff1a".getBytes(),
+            "[  ]hzzone:\u4e5f\u5c31\u5784\u65ad\u5e73\u53f0\u603b\u90e8\u5de5\u8d44\u8ddf\u8001\u4eba\u9000\u4f11\u91d1\u6da8\u5176\u4ed6\u6536\u5165\u5927\u591a\u4e0b\u8dcc\u6216\u5931\u4e1a\u5f52\u96f6(2026-02-06 07:20)\n".getBytes(),
+            "[-5]voTvo:\u524d\u63d0\u5c31\u8bf4\u9519\u4e86\uff0c\u6536\u5165\u8d8a\u6765\u8d8a\u4f4e\u597d\u5417(2026-02-06 10:16)\n".getBytes(),
+            "[-5]shocker:\u8d22\u5bcc\u96c6\u4e2d\u548c\u5b8f\u5927\u53d9\u4e8b\uff0c\u548c\u4e07\u5343\u666e\u901a\u5bb6\u5ead\u611f\u53d7\u76f8\u77db\u76fe\u3002(2026-02-06 10:22)\n".getBytes(),
+            "[-5]yourcarin0:\u9884\u5236\u83dc\u4e8b\u4ef6\u5fd8\u4e86\uff1f(2026-02-06 11:14)\n".getBytes(),
+            "[+5]whatswrong:\u5355\u6b21\u5355\u4eba\u8d39\u7528\u6da8\u4e86\uff0c\u4e0b\u9986\u5b50\u9891\u7387\u5927\u5e45\u964d\u4f4e(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.17.1