--- a/hotspot/src/cpu/ppc/vm/ppc.ad Fri Jun 02 13:48:01 2017 +0200
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad Fri Jun 02 16:32:39 2017 +0200
@@ -5842,6 +5842,16 @@
ins_pipe(pipe_class_default);
%}
+instruct rldicl(iRegLdst dst, iRegLsrc src, immI16 shift, immI16 mask_begin) %{
+ effect(DEF dst, USE src, USE shift, USE mask_begin);
+
+ size(4);
+ ins_encode %{
+ __ rldicl($dst$$Register, $src$$Register, $shift$$constant, $mask_begin$$constant);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
// Needed to postalloc expand loadConN: ConN is loaded as ConI
// leaving the upper 32 bits with sign-extension bits.
// This clears these bits: dst = src & 0xFFFFFFFF.
@@ -10519,6 +10529,16 @@
ins_pipe(pipe_class_default);
%}
+instruct extsh(iRegIdst dst, iRegIsrc src) %{
+ effect(DEF dst, USE src);
+
+ size(4);
+ ins_encode %{
+ __ extsh($dst$$Register, $src$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
// LShiftI 16 + RShiftI 16 converts short to int.
instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
match(Set dst (RShiftI (LShiftI src amount) amount));
@@ -12682,8 +12702,7 @@
// Just slightly faster than java implementation.
instruct bytes_reverse_int_Ex(iRegIdst dst, iRegIsrc src) %{
match(Set dst (ReverseBytesI src));
- predicate(UseCountLeadingZerosInstructionsPPC64);
- ins_cost(DEFAULT_COST);
+ ins_cost(7*DEFAULT_COST);
expand %{
immI16 imm24 %{ (int) 24 %}
@@ -12705,6 +12724,172 @@
%}
%}
+instruct bytes_reverse_long_Ex(iRegLdst dst, iRegLsrc src) %{
+ match(Set dst (ReverseBytesL src));
+ ins_cost(15*DEFAULT_COST);
+
+ expand %{
+ immI16 imm56 %{ (int) 56 %}
+ immI16 imm48 %{ (int) 48 %}
+ immI16 imm40 %{ (int) 40 %}
+ immI16 imm32 %{ (int) 32 %}
+ immI16 imm24 %{ (int) 24 %}
+ immI16 imm16 %{ (int) 16 %}
+ immI16 imm8 %{ (int) 8 %}
+ immI16 imm0 %{ (int) 0 %}
+ iRegLdst tmpL1;
+ iRegLdst tmpL2;
+ iRegLdst tmpL3;
+ iRegLdst tmpL4;
+ iRegLdst tmpL5;
+ iRegLdst tmpL6;
+
+ // src : |a|b|c|d|e|f|g|h|
+ rldicl(tmpL1, src, imm8, imm24); // tmpL1 : | | | |e|f|g|h|a|
+ rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |a| | | |e|
+ rldicl(tmpL3, tmpL2, imm32, imm0); // tmpL3 : | | | |e| | | |a|
+ rldicl(tmpL1, src, imm16, imm24); // tmpL1 : | | | |f|g|h|a|b|
+ rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |b| | | |f|
+ rldicl(tmpL4, tmpL2, imm40, imm0); // tmpL4 : | | |f| | | |b| |
+ orL_reg_reg(tmpL5, tmpL3, tmpL4); // tmpL5 : | | |f|e| | |b|a|
+ rldicl(tmpL1, src, imm24, imm24); // tmpL1 : | | | |g|h|a|b|c|
+ rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |c| | | |g|
+ rldicl(tmpL3, tmpL2, imm48, imm0); // tmpL3 : | |g| | | |c| | |
+ rldicl(tmpL1, src, imm32, imm24); // tmpL1 : | | | |h|a|b|c|d|
+ rldicl(tmpL2, tmpL1, imm32, imm24); // tmpL2 : | | | |d| | | |h|
+ rldicl(tmpL4, tmpL2, imm56, imm0); // tmpL4 : |h| | | |d| | | |
+ orL_reg_reg(tmpL6, tmpL3, tmpL4); // tmpL6 : |h|g| | |d|c| | |
+ orL_reg_reg(dst, tmpL5, tmpL6); // dst : |h|g|f|e|d|c|b|a|
+ %}
+%}
+
+instruct bytes_reverse_ushort_Ex(iRegIdst dst, iRegIsrc src) %{
+ match(Set dst (ReverseBytesUS src));
+ ins_cost(2*DEFAULT_COST);
+
+ expand %{
+ immI16 imm16 %{ (int) 16 %}
+ immI16 imm8 %{ (int) 8 %}
+
+ urShiftI_reg_imm(dst, src, imm8);
+ insrwi(dst, src, imm16, imm8);
+ %}
+%}
+
+instruct bytes_reverse_short_Ex(iRegIdst dst, iRegIsrc src) %{
+ match(Set dst (ReverseBytesS src));
+ ins_cost(3*DEFAULT_COST);
+
+ expand %{
+ immI16 imm16 %{ (int) 16 %}
+ immI16 imm8 %{ (int) 8 %}
+ iRegLdst tmpI1;
+
+ urShiftI_reg_imm(tmpI1, src, imm8);
+ insrwi(tmpI1, src, imm16, imm8);
+ extsh(dst, tmpI1);
+ %}
+%}
+
+// Load Integer reversed byte order
+instruct loadI_reversed(iRegIdst dst, indirect mem) %{
+ match(Set dst (ReverseBytesI (LoadI mem)));
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ lwbrx($dst$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Load Long - aligned and reversed
+instruct loadL_reversed(iRegLdst dst, indirect mem) %{
+ match(Set dst (ReverseBytesL (LoadL mem)));
+ predicate(VM_Version::has_ldbrx());
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ ldbrx($dst$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Load unsigned short / char reversed byte order
+instruct loadUS_reversed(iRegIdst dst, indirect mem) %{
+ match(Set dst (ReverseBytesUS (LoadUS mem)));
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ lhbrx($dst$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Load short reversed byte order
+instruct loadS_reversed(iRegIdst dst, indirect mem) %{
+ match(Set dst (ReverseBytesS (LoadS mem)));
+ ins_cost(MEMORY_REF_COST + DEFAULT_COST);
+
+ size(8);
+ ins_encode %{
+ __ lhbrx($dst$$Register, $mem$$Register);
+ __ extsh($dst$$Register, $dst$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Store Integer reversed byte order
+instruct storeI_reversed(iRegIsrc src, indirect mem) %{
+ match(Set mem (StoreI mem (ReverseBytesI src)));
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ stwbrx($src$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Store Long reversed byte order
+instruct storeL_reversed(iRegLsrc src, indirect mem) %{
+ match(Set mem (StoreL mem (ReverseBytesL src)));
+ predicate(VM_Version::has_stdbrx());
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ stdbrx($src$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Store unsigned short / char reversed byte order
+instruct storeUS_reversed(iRegIsrc src, indirect mem) %{
+ match(Set mem (StoreC mem (ReverseBytesUS src)));
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ sthbrx($src$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
+// Store short reversed byte order
+instruct storeS_reversed(iRegIsrc src, indirect mem) %{
+ match(Set mem (StoreC mem (ReverseBytesS src)));
+ ins_cost(MEMORY_REF_COST);
+
+ size(4);
+ ins_encode %{
+ __ sthbrx($src$$Register, $mem$$Register);
+ %}
+ ins_pipe(pipe_class_default);
+%}
+
//---------- Replicate Vector Instructions ------------------------------------
// Insrdi does replicate if src == dst.