diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index a0b6f5a17f7..44cc810faab 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -2593,7 +2593,7 @@ class StubGenerator: public StubCodeGenerator { address start = __ function_entry(); - Label L_doLast; + Label L_doLast, L_error; Register from = R3_ARG1; // source array address Register to = R4_ARG2; // destination array address @@ -2623,7 +2623,7 @@ class StubGenerator: public StubCodeGenerator { __ li (fifteen, 15); - // load unaligned from[0-15] to vsRet + // load unaligned from[0-15] to vRet __ lvx (vRet, from); __ lvx (vTmp1, fifteen, from); __ lvsl (fromPerm, from); @@ -2738,6 +2738,11 @@ class StubGenerator: public StubCodeGenerator { __ cmpwi (CCR0, keylen, 52); __ beq (CCR0, L_doLast); +#ifdef ASSERT + __ cmpwi (CCR0, keylen, 60); + __ bne (CCR0, L_error); +#endif + // 12th - 13th rounds __ vcipher (vRet, vRet, vKey1); __ vcipher (vRet, vRet, vKey2); @@ -2758,29 +2763,30 @@ class StubGenerator: public StubCodeGenerator { __ vcipher (vRet, vRet, vKey1); __ vcipherlast (vRet, vRet, vKey2); - // store result (unaligned) #ifdef VM_LITTLE_ENDIAN - __ lvsl (toPerm, to); -#else - __ lvsr (toPerm, to); -#endif - __ vspltisb (vTmp3, -1); - __ vspltisb (vTmp4, 0); - __ lvx (vTmp1, to); - __ lvx (vTmp2, fifteen, to); -#ifdef VM_LITTLE_ENDIAN - __ vperm (vTmp3, vTmp3, vTmp4, toPerm); // generate select mask - __ vxor (toPerm, toPerm, fSplt); // swap bytes -#else - __ vperm (vTmp3, vTmp4, vTmp3, toPerm); // generate select mask + // toPerm = 0x0F0E0D0C0B0A09080706050403020100 + __ lvsl (toPerm, keypos); // keypos is a multiple of 16 + __ vxor (toPerm, toPerm, fSplt); + + // Swap Bytes + __ vperm (vRet, vRet, vRet, toPerm); #endif - __ vperm (vTmp4, vRet, vRet, toPerm); // rotate data - __ vsel (vTmp2, vTmp4, vTmp2, vTmp3); - __ vsel (vTmp1, vTmp1, vTmp4, vTmp3); - __ stvx (vTmp2, fifteen, to); // store this one first (may alias) - __ stvx (vTmp1, to); + + // 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); __ blr(); + +#ifdef ASSERT + __ bind(L_error); + __ stop("aescrypt_encryptBlock: invalid key length"); +#endif return start; } @@ -2794,9 +2800,7 @@ class StubGenerator: public StubCodeGenerator { address start = __ function_entry(); - Label L_doLast; - Label L_do44; - Label L_do52; + Label L_doLast, L_do44, L_do52, L_error; Register from = R3_ARG1; // source array address Register to = R4_ARG2; // destination array address @@ -2827,7 +2831,7 @@ class StubGenerator: public StubCodeGenerator { __ li (fifteen, 15); - // load unaligned from[0-15] to vsRet + // load unaligned from[0-15] to vRet __ lvx (vRet, from); __ lvx (vTmp1, fifteen, from); __ lvsl (fromPerm, from); @@ -2856,6 +2860,11 @@ class StubGenerator: public StubCodeGenerator { __ cmpwi (CCR0, keylen, 52); __ beq (CCR0, L_do52); +#ifdef ASSERT + __ cmpwi (CCR0, keylen, 60); + __ bne (CCR0, L_error); +#endif + // load the 15th round key to vKey1 __ li (keypos, 240); __ lvx (vKey1, keypos, key); @@ -2892,6 +2901,7 @@ class StubGenerator: public StubCodeGenerator { __ b (L_doLast); + __ align(32); __ bind (L_do52); // load the 13th round key to vKey1 @@ -2918,6 +2928,7 @@ class StubGenerator: public StubCodeGenerator { __ b (L_doLast); + __ align(32); __ bind (L_do44); // load the 11th round key to vKey1 @@ -2995,29 +3006,30 @@ class StubGenerator: public StubCodeGenerator { __ vncipher (vRet, vRet, vKey4); __ vncipherlast (vRet, vRet, vKey5); - // store result (unaligned) -#ifdef VM_LITTLE_ENDIAN - __ lvsl (toPerm, to); -#else - __ lvsr (toPerm, to); -#endif - __ vspltisb (vTmp3, -1); - __ vspltisb (vTmp4, 0); - __ lvx (vTmp1, to); - __ lvx (vTmp2, fifteen, to); #ifdef VM_LITTLE_ENDIAN - __ vperm (vTmp3, vTmp3, vTmp4, toPerm); // generate select mask - __ vxor (toPerm, toPerm, fSplt); // swap bytes -#else - __ vperm (vTmp3, vTmp4, vTmp3, toPerm); // generate select mask + // toPerm = 0x0F0E0D0C0B0A09080706050403020100 + __ lvsl (toPerm, keypos); // keypos is a multiple of 16 + __ vxor (toPerm, toPerm, fSplt); + + // Swap Bytes + __ vperm (vRet, vRet, vRet, toPerm); #endif - __ vperm (vTmp4, vRet, vRet, toPerm); // rotate data - __ vsel (vTmp2, vTmp4, vTmp2, vTmp3); - __ vsel (vTmp1, vTmp1, vTmp4, vTmp3); - __ stvx (vTmp2, fifteen, to); // store this one first (may alias) - __ stvx (vTmp1, to); + + // 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); __ blr(); + +#ifdef ASSERT + __ bind(L_error); + __ stop("aescrypt_decryptBlock: invalid key length"); +#endif return start; }