diff --git a/src/hotspot/cpu/ppc/assembler_ppc.hpp b/src/hotspot/cpu/ppc/assembler_ppc.hpp index 3c444207b11..27eb14bdfd3 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.hpp @@ -544,6 +544,10 @@ class Assembler : public AbstractAssembler { STXVL_OPCODE = (31u << OPCODE_SHIFT | 397u << 1), LXVD2X_OPCODE = (31u << OPCODE_SHIFT | 844u << 1), STXVD2X_OPCODE = (31u << OPCODE_SHIFT | 972u << 1), + LXVW4X_OPCODE = (31u << OPCODE_SHIFT | 780u << 1), + STXVW4X_OPCODE = (31u << OPCODE_SHIFT | 908u << 1), + LXVB16X_OPCODE = (31u << OPCODE_SHIFT | 876u << 1), + STXVB16X_OPCODE= (31u << OPCODE_SHIFT | 1004u << 1), MTVSRD_OPCODE = (31u << OPCODE_SHIFT | 179u << 1), MTVSRDD_OPCODE = (31u << OPCODE_SHIFT | 435u << 1), MTVSRWZ_OPCODE = (31u << OPCODE_SHIFT | 243u << 1), @@ -2375,8 +2379,17 @@ class Assembler : public AbstractAssembler { inline void lxvd2x( VectorSRegister d, Register a, Register b); inline void stxvd2x( VectorSRegister d, Register a); inline void stxvd2x( VectorSRegister d, Register a, Register b); + inline void lxvw4x( VectorSRegister d, Register a); + inline void lxvw4x( VectorSRegister d, Register a, Register b); + inline void stxvw4x( VectorSRegister d, Register a); + inline void stxvw4x( VectorSRegister d, Register a, Register b); // Power9 + inline void lxvb16x( VectorSRegister d, Register a); + inline void lxvb16x( VectorSRegister d, Register a, Register b); + inline void stxvb16x( VectorSRegister d, Register a); + inline void stxvb16x( VectorSRegister d, Register a, Register b); + inline void lxv( VectorSRegister d, int si16, Register a); inline void stxv( VectorSRegister d, int si16, Register a); inline void lxvx( VectorSRegister d, Register a, Register b); @@ -2573,6 +2586,15 @@ class Assembler : public AbstractAssembler { inline void vec_perm(VectorRegister first_dest, VectorRegister second, VectorRegister perm); inline void vec_perm(VectorRegister dest, VectorRegister first, VectorRegister second, VectorRegister perm); + // Load/Store unaligned vectors with offs (multiple of 16). Byte versions require vp for Power8 LE. + inline void load_byte_vector_unaligned(VectorRegister dest, int offs, Register base, Register tmp, + VectorRegister vp); // vp should be pre-computed (see generator below) + inline void store_byte_vector_unaligned(VectorRegister val, int offs, Register base, Register tmp, + VectorRegister vp, VectorRegister vtmp = vnoreg); // clobbers val if no vtmp provided + inline void compute_vp_for_byte_vector_unaligned(VectorRegister dest, VectorRegister vtmp); + inline void load_word_vector_unaligned(VectorRegister dest, int offs, Register base, Register tmp); + inline void store_word_vector_unaligned(VectorRegister val, int offs, Register base, Register tmp); + // RegisterOrConstant versions. // These emitters choose between the versions using two registers and // those with register and immediate, depending on the content of roc. diff --git a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp index 482d01bdab2..412ed995cab 100644 --- a/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp +++ b/src/hotspot/cpu/ppc/assembler_ppc.inline.hpp @@ -864,6 +864,14 @@ inline void Assembler::lxvd2x( VectorSRegister d, Register s1) { e inline void Assembler::lxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( LXVD2X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); } inline void Assembler::stxvd2x( VectorSRegister d, Register s1) { emit_int32( STXVD2X_OPCODE | vsrs(d) | ra(0) | rb(s1)); } inline void Assembler::stxvd2x( VectorSRegister d, Register s1, Register s2) { emit_int32( STXVD2X_OPCODE | vsrs(d) | ra0mem(s1) | rb(s2)); } +inline void Assembler::lxvw4x( VectorSRegister d, Register s1) { emit_int32( LXVW4X_OPCODE | vsrt(d) | ra(0) | rb(s1)); } +inline void Assembler::lxvw4x( VectorSRegister d, Register s1, Register s2) { emit_int32( LXVW4X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); } +inline void Assembler::stxvw4x( VectorSRegister d, Register s1) { emit_int32( STXVW4X_OPCODE | vsrs(d) | ra(0) | rb(s1)); } +inline void Assembler::stxvw4x( VectorSRegister d, Register s1, Register s2) { emit_int32( STXVW4X_OPCODE | vsrs(d) | ra0mem(s1) | rb(s2)); } +inline void Assembler::lxvb16x( VectorSRegister d, Register s1) { emit_int32( LXVB16X_OPCODE | vsrt(d) | ra(0) | rb(s1)); } +inline void Assembler::lxvb16x( VectorSRegister d, Register s1, Register s2) { emit_int32( LXVB16X_OPCODE | vsrt(d) | ra0mem(s1) | rb(s2)); } +inline void Assembler::stxvb16x(VectorSRegister d, Register s1) { emit_int32( STXVB16X_OPCODE| vsrs(d) | ra(0) | rb(s1)); } +inline void Assembler::stxvb16x(VectorSRegister d, Register s1, Register s2) { emit_int32( STXVB16X_OPCODE| vsrs(d) | ra0mem(s1) | rb(s2)); } inline void Assembler::mtvsrd( VectorSRegister d, Register a) { emit_int32( MTVSRD_OPCODE | vsrt(d) | ra(a)); } inline void Assembler::mtvsrdd( VectorSRegister d, Register a, Register b) { emit_int32( MTVSRDD_OPCODE | vsrt(d) | ra(a) | rb(b)); } inline void Assembler::mfvsrd( Register d, VectorSRegister a) { emit_int32( MFVSRD_OPCODE | vsrs(a) | ra(d)); } @@ -1230,6 +1238,108 @@ inline void Assembler::vec_perm(VectorRegister dest, VectorRegister first, Vecto #endif } +inline void Assembler::load_byte_vector_unaligned(VectorRegister dest, int offs, Register base, Register tmp, + VectorRegister vp) { + VectorSRegister vsr = dest->to_vsr(); + if (PowerArchitecturePPC64 >= 9) { +#if !defined(VM_LITTLE_ENDIAN) + lxv(vsr, offs, base); // all vector load/store instructions use the same byte order on BE +#else + if (offs == 0) { + lxvb16x(vsr, base); + } else { + li(tmp, offs); + lxvb16x(vsr, base, tmp); + } +#endif + } else { // Power8 only supports very limited instructions + if (offs == 0) { + lxvd2x(vsr, base); + } else { + li(tmp, offs); + lxvd2x(vsr, base, tmp); + } +#if defined(VM_LITTLE_ENDIAN) + // need to swap bytes in both double-words + vperm(dest, dest, dest, vp); +#endif + } +} + +inline void Assembler::store_byte_vector_unaligned(VectorRegister val, int offs, Register base, Register tmp, + VectorRegister vp, VectorRegister vtmp) { + VectorSRegister vsr = val->to_vsr(); + if (PowerArchitecturePPC64 >= 9) { +#if !defined(VM_LITTLE_ENDIAN) + stxv(vsr, offs, base); // all vector load/store instructions use the same byte order on BE +#else + if (offs == 0) { + stxvb16x(vsr, base); + } else { + li(tmp, offs); + stxvb16x(vsr, base, tmp); + } +#endif + } else { // Power8 only supports very limited instructions +#if defined(VM_LITTLE_ENDIAN) + // need to swap bytes in both double-words + if (vtmp != vnoreg) { + vperm(vtmp, val, val, vp); + vsr = vtmp->to_vsr(); + } else { + vperm(val, val, val, vp); // clobbers val! + } +#endif + if (offs == 0) { + stxvd2x(vsr, base); + } else { + li(tmp, offs); + stxvd2x(vsr, base, tmp); + } + } +} + +inline void Assembler::compute_vp_for_byte_vector_unaligned(VectorRegister dest, VectorRegister vtmp) { +#if defined(VM_LITTLE_ENDIAN) + if (PowerArchitecturePPC64 < 9) { + li(R0, 0); + vspltisb(vtmp, 7); // vtmp = [7, ..., 7] + lvsl(dest, R0); // dest = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + vxor(dest, dest, vtmp); // dest = [7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8] + } +#endif +} + +inline void Assembler::load_word_vector_unaligned(VectorRegister dest, int offs, Register base, Register tmp) { + VectorSRegister vsr = dest->to_vsr(); +#if !defined(VM_LITTLE_ENDIAN) + if (PowerArchitecturePPC64 >= 9) { + lxv(vsr, offs, base); // all vector load/store instructions use the same byte order on BE + } else +#endif + if (offs == 0) { + lxvw4x(vsr, base); + } else { + li(tmp, offs); + lxvw4x(vsr, base, tmp); + } +} + +inline void Assembler::store_word_vector_unaligned(VectorRegister val, int offs, Register base, Register tmp) { + VectorSRegister vsr = val->to_vsr(); +#if !defined(VM_LITTLE_ENDIAN) + if (PowerArchitecturePPC64 >= 9) { + stxv(vsr, offs, base); // all vector load/store instructions use the same byte order on BE + } else +#endif + if (offs == 0) { + stxvw4x(vsr, base); + } else { + li(tmp, offs); + stxvw4x(vsr, base, tmp); + } +} + inline void Assembler::load_const(Register d, void* x, Register tmp) { load_const(d, (long)x, tmp); } diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index f272bffed92..dc9d6beb9d9 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -2762,10 +2762,8 @@ class StubGenerator: public StubCodeGenerator { Register to = R4_ARG2; // destination array address Register key = R5_ARG3; // round key array - Register keylen = R8; - Register temp = R9; - Register keypos = R10; - Register fifteen = R12; + Register keylen = R6; + Register tmp = R7; VectorRegister vRet = VR0; @@ -2774,68 +2772,27 @@ class StubGenerator: public StubCodeGenerator { VectorRegister vKey3 = VR3; VectorRegister vKey4 = VR4; - VectorRegister fromPerm = VR5; - VectorRegister keyPerm = VR6; - VectorRegister toPerm = VR7; - VectorRegister fSplt = VR8; + VectorRegister vp = VR6; // permute vector for byte vector accesses on P8 LE - VectorRegister vTmp1 = VR9; - VectorRegister vTmp2 = VR10; - VectorRegister vTmp3 = VR11; - VectorRegister vTmp4 = VR12; - - __ li (fifteen, 15); + __ compute_vp_for_byte_vector_unaligned(vp, /*temp*/ vRet); // load unaligned from[0-15] to vRet - __ lvx (vRet, from); - __ lvx (vTmp1, fifteen, from); - __ lvsl (fromPerm, from); -#ifdef VM_LITTLE_ENDIAN - __ vspltisb (fSplt, 0x0f); - __ vxor (fromPerm, fromPerm, fSplt); -#endif - __ vperm (vRet, vRet, vTmp1, fromPerm); + __ load_byte_vector_unaligned(vRet, 0, from, tmp, vp); + + // load the 1st round key to vKey1 + __ load_word_vector_unaligned(vKey1, 0, key, tmp); // load keylen (44 or 52 or 60) __ lwz (keylen, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT), key); - // to load keys - __ load_perm (keyPerm, key); -#ifdef VM_LITTLE_ENDIAN - __ vspltisb (vTmp2, -16); - __ vrld (keyPerm, keyPerm, vTmp2); - __ vrld (keyPerm, keyPerm, vTmp2); - __ vsldoi (keyPerm, keyPerm, keyPerm, 8); -#endif - - // load the 1st round key to vTmp1 - __ lvx (vTmp1, key); - __ li (keypos, 16); - __ lvx (vKey1, keypos, key); - __ vec_perm (vTmp1, vKey1, keyPerm); - // 1st round - __ vxor (vRet, vRet, vTmp1); - - // load the 2nd round key to vKey1 - __ li (keypos, 32); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vKey2, keyPerm); - - // load the 3rd round key to vKey2 - __ li (keypos, 48); - __ lvx (vKey3, keypos, key); - __ vec_perm (vKey2, vKey3, keyPerm); - - // load the 4th round key to vKey3 - __ li (keypos, 64); - __ lvx (vKey4, keypos, key); - __ vec_perm (vKey3, vKey4, keyPerm); + __ vxor (vRet, vRet, vKey1); - // load the 5th round key to vKey4 - __ li (keypos, 80); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey4, vTmp1, keyPerm); + // load the 2nd - 5th round key to vKey1 - vKey4 + __ load_word_vector_unaligned(vKey1, 16, key, tmp); + __ load_word_vector_unaligned(vKey2, 32, key, tmp); + __ load_word_vector_unaligned(vKey3, 48, key, tmp); + __ load_word_vector_unaligned(vKey4, 64, key, tmp); // 2nd - 5th rounds __ vcipher (vRet, vRet, vKey1); @@ -2843,25 +2800,11 @@ class StubGenerator: public StubCodeGenerator { __ vcipher (vRet, vRet, vKey3); __ vcipher (vRet, vRet, vKey4); - // load the 6th round key to vKey1 - __ li (keypos, 96); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); - - // load the 7th round key to vKey2 - __ li (keypos, 112); - __ lvx (vKey3, keypos, key); - __ vec_perm (vKey2, vKey3, keyPerm); - - // load the 8th round key to vKey3 - __ li (keypos, 128); - __ lvx (vKey4, keypos, key); - __ vec_perm (vKey3, vKey4, keyPerm); - - // load the 9th round key to vKey4 - __ li (keypos, 144); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey4, vTmp1, keyPerm); + // load the 6th - 9th round key to vKey1 - vKey4 + __ load_word_vector_unaligned(vKey1, 80, key, tmp); + __ load_word_vector_unaligned(vKey2, 96, key, tmp); + __ load_word_vector_unaligned(vKey3, 112, key, tmp); + __ load_word_vector_unaligned(vKey4, 128, key, tmp); // 6th - 9th rounds __ vcipher (vRet, vRet, vKey1); @@ -2869,15 +2812,9 @@ class StubGenerator: public StubCodeGenerator { __ vcipher (vRet, vRet, vKey3); __ vcipher (vRet, vRet, vKey4); - // load the 10th round key to vKey1 - __ li (keypos, 160); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); - - // load the 11th round key to vKey2 - __ li (keypos, 176); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey2, vTmp1, keyPerm); + // load the 10th - 11th round key to vKey1 - vKey2 + __ load_word_vector_unaligned(vKey1, 144, key, tmp); + __ load_word_vector_unaligned(vKey2, 160, key, tmp); // if all round keys are loaded, skip next 4 rounds __ cmpwi (CR0, keylen, 44); @@ -2887,15 +2824,9 @@ class StubGenerator: public StubCodeGenerator { __ vcipher (vRet, vRet, vKey1); __ vcipher (vRet, vRet, vKey2); - // load the 12th round key to vKey1 - __ li (keypos, 192); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); - - // load the 13th round key to vKey2 - __ li (keypos, 208); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey2, vTmp1, keyPerm); + // load the 12th - 13th round key to vKey1 - vKey2 + __ load_word_vector_unaligned(vKey1, 176, key, tmp); + __ load_word_vector_unaligned(vKey2, 192, key, tmp); // if all round keys are loaded, skip next 2 rounds __ cmpwi (CR0, keylen, 52); @@ -2910,15 +2841,9 @@ class StubGenerator: public StubCodeGenerator { __ vcipher (vRet, vRet, vKey1); __ vcipher (vRet, vRet, vKey2); - // load the 14th round key to vKey1 - __ li (keypos, 224); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vTmp1, vKey2, keyPerm); - - // load the 15th round key to vKey2 - __ li (keypos, 240); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey2, vTmp1, keyPerm); + // load the 14th - 15th round key to vKey1 - vKey2 + __ load_word_vector_unaligned(vKey1, 208, key, tmp); + __ load_word_vector_unaligned(vKey2, 224, key, tmp); __ bind(L_doLast); @@ -2926,23 +2851,8 @@ class StubGenerator: public StubCodeGenerator { __ vcipher (vRet, vRet, vKey1); __ vcipherlast (vRet, vRet, vKey2); -#ifdef VM_LITTLE_ENDIAN - // toPerm = 0x0F0E0D0C0B0A09080706050403020100 - __ lvsl (toPerm, keypos); // keypos is a multiple of 16 - __ vxor (toPerm, toPerm, fSplt); - - // Swap Bytes - __ vperm (vRet, vRet, vRet, toPerm); -#endif - // store result (unaligned) - // Note: We can't use a read-modify-write sequence which touches additional Bytes. - Register lo = temp, hi = fifteen; // Reuse - __ vsldoi (vTmp1, vRet, vRet, 8); - __ mfvrd (hi, vRet); - __ mfvrd (lo, vTmp1); - __ std (hi, 0 LITTLE_ENDIAN_ONLY(+ 8), to); - __ std (lo, 0 BIG_ENDIAN_ONLY(+ 8), to); + __ store_byte_vector_unaligned(vRet, 0, to, tmp, vp); __ blr(); @@ -2970,10 +2880,8 @@ class StubGenerator: public StubCodeGenerator { Register to = R4_ARG2; // destination array address Register key = R5_ARG3; // round key array - Register keylen = R8; - Register temp = R9; - Register keypos = R10; - Register fifteen = R12; + Register keylen = R6; + Register tmp = R7; VectorRegister vRet = VR0; @@ -2983,41 +2891,16 @@ class StubGenerator: public StubCodeGenerator { VectorRegister vKey4 = VR4; VectorRegister vKey5 = VR5; - VectorRegister fromPerm = VR6; - VectorRegister keyPerm = VR7; - VectorRegister toPerm = VR8; - VectorRegister fSplt = VR9; - - VectorRegister vTmp1 = VR10; - VectorRegister vTmp2 = VR11; - VectorRegister vTmp3 = VR12; - VectorRegister vTmp4 = VR13; + VectorRegister vp = VR6; // permute vector for byte vector accesses on P8 LE - __ li (fifteen, 15); + __ compute_vp_for_byte_vector_unaligned(vp, /*temp*/ vRet); // load unaligned from[0-15] to vRet - __ lvx (vRet, from); - __ lvx (vTmp1, fifteen, from); - __ lvsl (fromPerm, from); -#ifdef VM_LITTLE_ENDIAN - __ vspltisb (fSplt, 0x0f); - __ vxor (fromPerm, fromPerm, fSplt); -#endif - __ vperm (vRet, vRet, vTmp1, fromPerm); // align [and byte swap in LE] + __ load_byte_vector_unaligned(vRet, 0, from, tmp, vp); // load keylen (44 or 52 or 60) __ lwz (keylen, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT), key); - // to load keys - __ load_perm (keyPerm, key); -#ifdef VM_LITTLE_ENDIAN - __ vxor (vTmp2, vTmp2, vTmp2); - __ vspltisb (vTmp2, -16); - __ vrld (keyPerm, keyPerm, vTmp2); - __ vrld (keyPerm, keyPerm, vTmp2); - __ vsldoi (keyPerm, keyPerm, keyPerm, 8); -#endif - __ cmpwi (CR0, keylen, 44); __ beq (CR0, L_do44); @@ -3029,32 +2912,12 @@ class StubGenerator: public StubCodeGenerator { __ bne (CR0, L_error); #endif - // load the 15th round key to vKey1 - __ li (keypos, 240); - __ lvx (vKey1, keypos, key); - __ li (keypos, 224); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vKey2, vKey1, keyPerm); - - // load the 14th round key to vKey2 - __ li (keypos, 208); - __ lvx (vKey3, keypos, key); - __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - - // load the 13th round key to vKey3 - __ li (keypos, 192); - __ lvx (vKey4, keypos, key); - __ vec_perm (vKey3, vKey4, vKey3, keyPerm); - - // load the 12th round key to vKey4 - __ li (keypos, 176); - __ lvx (vKey5, keypos, key); - __ vec_perm (vKey4, vKey5, vKey4, keyPerm); - - // load the 11th round key to vKey5 - __ li (keypos, 160); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey5, vTmp1, vKey5, keyPerm); + // load the 15th - 11th round key to vKey1 - vKey5 + __ load_word_vector_unaligned(vKey1, 224, key, tmp); + __ load_word_vector_unaligned(vKey2, 208, key, tmp); + __ load_word_vector_unaligned(vKey3, 192, key, tmp); + __ load_word_vector_unaligned(vKey4, 176, key, tmp); + __ load_word_vector_unaligned(vKey5, 160, key, tmp); // 1st - 5th rounds __ vxor (vRet, vRet, vKey1); @@ -3068,22 +2931,10 @@ class StubGenerator: public StubCodeGenerator { __ align(32); __ bind (L_do52); - // load the 13th round key to vKey1 - __ li (keypos, 208); - __ lvx (vKey1, keypos, key); - __ li (keypos, 192); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vKey2, vKey1, keyPerm); - - // load the 12th round key to vKey2 - __ li (keypos, 176); - __ lvx (vKey3, keypos, key); - __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - - // load the 11th round key to vKey3 - __ li (keypos, 160); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey3, vTmp1, vKey3, keyPerm); + // load the 13th - 11th round key to vKey1 - vKey3 + __ load_word_vector_unaligned(vKey1, 192, key, tmp); + __ load_word_vector_unaligned(vKey2, 176, key, tmp); + __ load_word_vector_unaligned(vKey3, 160, key, tmp); // 1st - 3rd rounds __ vxor (vRet, vRet, vKey1); @@ -3096,41 +2947,19 @@ class StubGenerator: public StubCodeGenerator { __ bind (L_do44); // load the 11th round key to vKey1 - __ li (keypos, 176); - __ lvx (vKey1, keypos, key); - __ li (keypos, 160); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey1, vTmp1, vKey1, keyPerm); + __ load_word_vector_unaligned(vKey1, 160, key, tmp); // 1st round __ vxor (vRet, vRet, vKey1); __ bind (L_doLast); - // load the 10th round key to vKey1 - __ li (keypos, 144); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vKey2, vTmp1, keyPerm); - - // load the 9th round key to vKey2 - __ li (keypos, 128); - __ lvx (vKey3, keypos, key); - __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - - // load the 8th round key to vKey3 - __ li (keypos, 112); - __ lvx (vKey4, keypos, key); - __ vec_perm (vKey3, vKey4, vKey3, keyPerm); - - // load the 7th round key to vKey4 - __ li (keypos, 96); - __ lvx (vKey5, keypos, key); - __ vec_perm (vKey4, vKey5, vKey4, keyPerm); - - // load the 6th round key to vKey5 - __ li (keypos, 80); - __ lvx (vTmp1, keypos, key); - __ vec_perm (vKey5, vTmp1, vKey5, keyPerm); + // load the 10th - 6th round key to vKey1 - vKey5 + __ load_word_vector_unaligned(vKey1, 144, key, tmp); + __ load_word_vector_unaligned(vKey2, 128, key, tmp); + __ load_word_vector_unaligned(vKey3, 112, key, tmp); + __ load_word_vector_unaligned(vKey4, 96, key, tmp); + __ load_word_vector_unaligned(vKey5, 80, key, tmp); // last 10th - 6th rounds __ vncipher (vRet, vRet, vKey1); @@ -3139,29 +2968,12 @@ class StubGenerator: public StubCodeGenerator { __ vncipher (vRet, vRet, vKey4); __ vncipher (vRet, vRet, vKey5); - // load the 5th round key to vKey1 - __ li (keypos, 64); - __ lvx (vKey2, keypos, key); - __ vec_perm (vKey1, vKey2, vTmp1, keyPerm); - - // load the 4th round key to vKey2 - __ li (keypos, 48); - __ lvx (vKey3, keypos, key); - __ vec_perm (vKey2, vKey3, vKey2, keyPerm); - - // load the 3rd round key to vKey3 - __ li (keypos, 32); - __ lvx (vKey4, keypos, key); - __ vec_perm (vKey3, vKey4, vKey3, keyPerm); - - // load the 2nd round key to vKey4 - __ li (keypos, 16); - __ lvx (vKey5, keypos, key); - __ vec_perm (vKey4, vKey5, vKey4, keyPerm); - - // load the 1st round key to vKey5 - __ lvx (vTmp1, key); - __ vec_perm (vKey5, vTmp1, vKey5, keyPerm); + // load the 5th - 1st round key to vKey1 - vKey5 + __ load_word_vector_unaligned(vKey1, 64, key, tmp); + __ load_word_vector_unaligned(vKey2, 48, key, tmp); + __ load_word_vector_unaligned(vKey3, 32, key, tmp); + __ load_word_vector_unaligned(vKey4, 16, key, tmp); + __ load_word_vector_unaligned(vKey5, 0, key, tmp); // last 5th - 1th rounds __ vncipher (vRet, vRet, vKey1); @@ -3170,23 +2982,8 @@ class StubGenerator: public StubCodeGenerator { __ vncipher (vRet, vRet, vKey4); __ vncipherlast (vRet, vRet, vKey5); -#ifdef VM_LITTLE_ENDIAN - // toPerm = 0x0F0E0D0C0B0A09080706050403020100 - __ lvsl (toPerm, keypos); // keypos is a multiple of 16 - __ vxor (toPerm, toPerm, fSplt); - - // Swap Bytes - __ vperm (vRet, vRet, vRet, toPerm); -#endif - // store result (unaligned) - // Note: We can't use a read-modify-write sequence which touches additional Bytes. - Register lo = temp, hi = fifteen; // Reuse - __ vsldoi (vTmp1, vRet, vRet, 8); - __ mfvrd (hi, vRet); - __ mfvrd (lo, vTmp1); - __ std (hi, 0 LITTLE_ENDIAN_ONLY(+ 8), to); - __ std (lo, 0 BIG_ENDIAN_ONLY(+ 8), to); + __ store_byte_vector_unaligned(vRet, 0, to, tmp, vp); __ blr();