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
@@ -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
@@ -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
@@ -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,
@@ -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,
new file mode 100644
@@ -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
@@ -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();
@@ -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
@@ -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
};
@@ -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.
@@ -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");
@@ -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); }
@@ -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:
@@ -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") \
@@ -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") \
@@ -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,
@@ -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*)
new file mode 100644
@@ -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.
+```
@@ -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;
@@ -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)
@@ -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) &&
@@ -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));
@@ -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:
@@ -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
@@ -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");
@@ -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();
@@ -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: {
@@ -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;
@@ -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.
@@ -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.
@@ -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;
@@ -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;
+ }
}
new file mode 100644
@@ -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();
+ }
+}
new file mode 100644
@@ -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