Skip to content

Instantly share code, notes, and snippets.

@gut
Created April 7, 2017 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gut/3d5f7984ef3114113b224853867bc906 to your computer and use it in GitHub Desktop.
Save gut/3d5f7984ef3114113b224853867bc906 to your computer and use it in GitHub Desktop.
OpenJDK 8 bug when implementing muladd on ppc
diff -r 92cb89e23f3e src/cpu/ppc/vm/stubGenerator_ppc.cpp
--- a/src/cpu/ppc/vm/stubGenerator_ppc.cpp Tue Apr 04 02:49:51 2017 -0700
+++ b/src/cpu/ppc/vm/stubGenerator_ppc.cpp Fri Apr 07 11:03:29 2017 -0300
@@ -2473,6 +2473,81 @@
__ blr();
}
+ /**
+ * Arguments:
+ *
+ * Input:
+ * R3_ARG1 - out address
+ * R4_ARG2 - in address
+ * R5_ARG3 - offset
+ * R6_ARG4 - len
+ * R7_ARG5 - k
+ * Output:
+ * R3_RET - carry
+ */
+ address generate_mulAdd() {
+ __ align(CodeEntryAlignment);
+ StubCodeMark mark(this, "StubRoutines", "mulAdd");
+
+ address start = __ function_entry();
+
+ // args
+ const Register out = R3_ARG1;
+ const Register in = R4_ARG2;
+ const Register offset = R5_ARG3;
+ const Register len = R6_ARG4;
+ const Register k = R7_ARG5;
+
+ // output
+ const Register ret = R3_RET;
+
+ // temporaries
+ const Register a = R8;
+ const Register b = R9;
+ const Register carry = R10;
+
+ // Labels
+ Label MULADD_LOOP, SKIP;
+
+ // Prepare variables
+ __ li (carry, 0);
+
+ // Make sure length is positive.
+ __ cmpdi (CCR0, len, 0);
+ __ ble (CCR0, SKIP);
+
+ __ addi (offset, offset, -1 );
+
+ __ clrldi (k, k, 32 );
+ __ mtctr (len);
+ __ addi (len, len, -1 );
+ // offset and len will be adjusted to 4 bytes
+ __ sldi (offset, offset, 2 );
+ __ sldi (len, len, 2 );
+
+ // Main loop
+ __ bind(MULADD_LOOP);
+ __ lwzx (a, len, in );
+ __ lwzx (b, offset, out );
+ // Using mulld instead of mullw because the parameters need to be
+ // considered as unsigned even if bit 31 is set (aka negative int)
+ __ mulld (a, a, k );
+ __ add (b, carry, b );
+ __ add (b, a, b );
+ __ stwx (b, offset, out );
+ __ srdi (carry, b, 32 );
+ __ addi (offset, offset, -4 );
+ __ addi (len, len, -4 );
+ __ bdnz (MULADD_LOOP);
+
+ __ bind(SKIP);
+ __ mr (ret, carry );
+
+ __ blr();
+
+ return start;
+ }
+
// Initialization
void generate_initial() {
// Generates all stubs and initializes the entry points
@@ -2518,6 +2593,9 @@
generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry,
&StubRoutines::_safefetchN_fault_pc,
&StubRoutines::_safefetchN_continuation_pc);
+ if (UseMulAddIntrinsic) {
+ StubRoutines::_mulAdd = generate_mulAdd();
+ }
if (UseAESIntrinsics) {
StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
diff -r 92cb89e23f3e src/cpu/ppc/vm/vm_version_ppc.cpp
--- a/src/cpu/ppc/vm/vm_version_ppc.cpp Tue Apr 04 02:49:51 2017 -0700
+++ b/src/cpu/ppc/vm/vm_version_ppc.cpp Fri Apr 07 11:03:29 2017 -0300
@@ -201,6 +201,9 @@
FLAG_SET_DEFAULT(UseSHA512Intrinsics, false);
}
+ if (FLAG_IS_DEFAULT(UseMulAddIntrinsic)) {
+ UseMulAddIntrinsic = true;
+ }
}
void VM_Version::print_features() {
/*
* Copyright (c) 2015, 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.
*/
//package compiler.intrinsics.bigInteger;
import java.math.BigInteger;
import java.util.Random;
public class TestMulAdd {
public static void main(String args[]) throws Exception {
int n = 1;
if (args.length >=1) {
n = Integer.parseInt(args[0]);
}
BigInteger newsum = new BigInteger("0");
BigInteger b1, newres;
Random rand = new Random();
long seed = System.nanoTime();
Random rand1 = new Random();
long seed1 = System.nanoTime();
rand.setSeed(seed);
rand1.setSeed(seed1);
for (int j = 0; j < n; j++) {
int rand_int = rand1.nextInt(3136)+32;
b1 = new BigInteger(rand_int, rand);
//System.out.println(b1);
newres = b1.multiply(b1);
newsum = newsum.add(newres);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment