Skip to content

Commit f6c203e

Browse files
committed
8314949: linux PPC64 Big Endian: Implementation of Foreign Function & Memory API
Reviewed-by: mcimadamore, jvernee
1 parent a01b3fb commit f6c203e

File tree

11 files changed

+303
-16
lines changed

11 files changed

+303
-16
lines changed

src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const {
4747
}
4848

4949
bool ForeignGlobals::is_foreign_linker_supported() {
50-
#ifdef ABI_ELFv2
50+
#ifdef LINUX
5151
return true;
5252
#else
5353
return false;

src/java.base/share/classes/jdk/internal/foreign/CABI.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public enum CABI {
3939
LINUX_AARCH_64,
4040
MAC_OS_AARCH_64,
4141
WIN_AARCH_64,
42+
LINUX_PPC_64,
4243
LINUX_PPC_64_LE,
4344
LINUX_RISCV_64,
4445
LINUX_S390,
@@ -74,6 +75,10 @@ private static CABI computeCurrent() {
7475
// The Linux ABI follows the standard AAPCS ABI
7576
return LINUX_AARCH_64;
7677
}
78+
} else if (arch.equals("ppc64")) {
79+
if (OperatingSystem.isLinux()) {
80+
return LINUX_PPC_64;
81+
}
7782
} else if (arch.equals("ppc64le")) {
7883
if (OperatingSystem.isLinux()) {
7984
return LINUX_PPC_64_LE;

src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker;
3131
import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker;
3232
import jdk.internal.foreign.abi.fallback.FallbackLinker;
33+
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64Linker;
3334
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker;
3435
import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker;
3536
import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker;
@@ -60,7 +61,8 @@
6061

6162
public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker,
6263
SysVx64Linker, WindowsAArch64Linker,
63-
Windowsx64Linker, LinuxPPC64leLinker,
64+
Windowsx64Linker,
65+
LinuxPPC64Linker, LinuxPPC64leLinker,
6466
LinuxRISCV64Linker, LinuxS390Linker,
6567
FallbackLinker {
6668

src/java.base/share/classes/jdk/internal/foreign/abi/Binding.java

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,18 @@ static Dup dup() {
276276
return Dup.INSTANCE;
277277
}
278278

279+
static ShiftLeft shiftLeft(int shiftAmount) {
280+
if (shiftAmount <= 0)
281+
throw new IllegalArgumentException("shiftAmount must be positive");
282+
return new ShiftLeft(shiftAmount);
283+
}
284+
285+
static ShiftRight shiftRight(int shiftAmount) {
286+
if (shiftAmount <= 0)
287+
throw new IllegalArgumentException("shiftAmount must be positive");
288+
return new ShiftRight(shiftAmount);
289+
}
290+
279291
static Binding cast(Class<?> fromType, Class<?> toType) {
280292
if (fromType == int.class) {
281293
if (toType == boolean.class) {
@@ -286,6 +298,8 @@ static Binding cast(Class<?> fromType, Class<?> toType) {
286298
return Cast.INT_TO_SHORT;
287299
} else if (toType == char.class) {
288300
return Cast.INT_TO_CHAR;
301+
} else if (toType == long.class) {
302+
return Cast.INT_TO_LONG;
289303
}
290304
} else if (toType == int.class) {
291305
if (fromType == boolean.class) {
@@ -296,6 +310,24 @@ static Binding cast(Class<?> fromType, Class<?> toType) {
296310
return Cast.SHORT_TO_INT;
297311
} else if (fromType == char.class) {
298312
return Cast.CHAR_TO_INT;
313+
} else if (fromType == long.class) {
314+
return Cast.LONG_TO_INT;
315+
}
316+
} else if (fromType == long.class) {
317+
if (toType == byte.class) {
318+
return Cast.LONG_TO_BYTE;
319+
} else if (toType == short.class) {
320+
return Cast.LONG_TO_SHORT;
321+
} else if (toType == char.class) {
322+
return Cast.LONG_TO_CHAR;
323+
}
324+
} else if (toType == long.class) {
325+
if (fromType == byte.class) {
326+
return Cast.BYTE_TO_LONG;
327+
} else if (fromType == short.class) {
328+
return Cast.SHORT_TO_LONG;
329+
} else if (fromType == char.class) {
330+
return Cast.CHAR_TO_LONG;
299331
}
300332
}
301333
throw new IllegalArgumentException("Unknown conversion: " + fromType + " -> " + toType);
@@ -387,6 +419,24 @@ public Binding.Builder dup() {
387419
return this;
388420
}
389421

422+
// Converts to long if needed then shifts left by the given number of Bytes.
423+
public Binding.Builder shiftLeft(int shiftAmount, Class<?> type) {
424+
if (type != long.class) {
425+
bindings.add(Binding.cast(type, long.class));
426+
}
427+
bindings.add(Binding.shiftLeft(shiftAmount));
428+
return this;
429+
}
430+
431+
// Shifts right by the given number of Bytes then converts from long if needed.
432+
public Binding.Builder shiftRight(int shiftAmount, Class<?> type) {
433+
bindings.add(Binding.shiftRight(shiftAmount));
434+
if (type != long.class) {
435+
bindings.add(Binding.cast(long.class, type));
436+
}
437+
return this;
438+
}
439+
390440
public List<Binding> build() {
391441
return List.copyOf(bindings);
392442
}
@@ -670,6 +720,52 @@ public void interpret(Deque<Object> stack, StoreFunc storeFunc,
670720
}
671721
}
672722

723+
/**
724+
* ShiftLeft([shiftAmount])
725+
* Shifts the Bytes on the top of the operand stack (64 bit unsigned).
726+
* Shifts left by the given number of Bytes.
727+
*/
728+
record ShiftLeft(int shiftAmount) implements Binding {
729+
730+
@Override
731+
public void verify(Deque<Class<?>> stack) {
732+
Class<?> last = stack.pop();
733+
SharedUtils.checkType(last, long.class);
734+
stack.push(long.class);
735+
}
736+
737+
@Override
738+
public void interpret(Deque<Object> stack, StoreFunc storeFunc,
739+
LoadFunc loadFunc, SegmentAllocator allocator) {
740+
long l = (long) stack.pop();
741+
l <<= (shiftAmount * Byte.SIZE);
742+
stack.push(l);
743+
}
744+
}
745+
746+
/**
747+
* ShiftRight([shiftAmount])
748+
* Shifts the Bytes on the top of the operand stack (64 bit unsigned).
749+
* Shifts right by the given number of Bytes.
750+
*/
751+
record ShiftRight(int shiftAmount) implements Binding {
752+
753+
@Override
754+
public void verify(Deque<Class<?>> stack) {
755+
Class<?> last = stack.pop();
756+
SharedUtils.checkType(last, long.class);
757+
stack.push(long.class);
758+
}
759+
760+
@Override
761+
public void interpret(Deque<Object> stack, StoreFunc storeFunc,
762+
LoadFunc loadFunc, SegmentAllocator allocator) {
763+
long l = (long) stack.pop();
764+
l >>>= (shiftAmount * Byte.SIZE);
765+
stack.push(l);
766+
}
767+
}
768+
673769
/**
674770
* CAST([fromType], [toType])
675771
* Pop a [fromType] from the stack, convert it to [toType], and push the resulting
@@ -690,10 +786,21 @@ public void interpret(Deque<Object> stack, StoreFunc storeFunc,
690786
INT_TO_BYTE(int.class, byte.class),
691787
INT_TO_CHAR(int.class, char.class),
692788
INT_TO_SHORT(int.class, short.class),
789+
INT_TO_LONG(int.class, long.class),
790+
693791
BOOLEAN_TO_INT(boolean.class, int.class),
694792
BYTE_TO_INT(byte.class, int.class),
695793
CHAR_TO_INT(char.class, int.class),
696-
SHORT_TO_INT(short.class, int.class);
794+
SHORT_TO_INT(short.class, int.class),
795+
LONG_TO_INT(long.class, int.class),
796+
797+
LONG_TO_BYTE(long.class, byte.class),
798+
LONG_TO_SHORT(long.class, short.class),
799+
LONG_TO_CHAR(long.class, char.class),
800+
801+
BYTE_TO_LONG(byte.class, long.class),
802+
SHORT_TO_LONG(short.class, long.class),
803+
CHAR_TO_LONG(char.class, long.class);
697804

698805
private final Class<?> fromType;
699806
private final Class<?> toType;

src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
import jdk.internal.foreign.abi.Binding.Cast;
4040
import jdk.internal.foreign.abi.Binding.Copy;
4141
import jdk.internal.foreign.abi.Binding.Dup;
42+
import jdk.internal.foreign.abi.Binding.ShiftLeft;
43+
import jdk.internal.foreign.abi.Binding.ShiftRight;
4244
import jdk.internal.foreign.abi.Binding.UnboxAddress;
4345
import jdk.internal.foreign.abi.Binding.VMLoad;
4446
import jdk.internal.foreign.abi.Binding.VMStore;
@@ -463,6 +465,8 @@ private void doBindings(List<Binding> bindings) {
463465
case BoxAddress boxAddress -> emitBoxAddress(boxAddress);
464466
case UnboxAddress unused -> emitUnboxAddress();
465467
case Dup unused -> emitDupBinding();
468+
case ShiftLeft shiftLeft -> emitShiftLeft(shiftLeft);
469+
case ShiftRight shiftRight -> emitShiftRight(shiftRight);
466470
case Cast cast -> emitCast(cast);
467471
}
468472
}
@@ -725,6 +729,20 @@ private void emitDupBinding() {
725729
pushType(dupType);
726730
}
727731

732+
private void emitShiftLeft(ShiftLeft shiftLeft) {
733+
popType(long.class);
734+
cb.constantInstruction(shiftLeft.shiftAmount() * Byte.SIZE);
735+
cb.lshl();
736+
pushType(long.class);
737+
}
738+
739+
private void emitShiftRight(ShiftRight shiftRight) {
740+
popType(long.class);
741+
cb.constantInstruction(shiftRight.shiftAmount() * Byte.SIZE);
742+
cb.lushr();
743+
pushType(long.class);
744+
}
745+
728746
private void emitCast(Cast cast) {
729747
Class<?> fromType = cast.fromType();
730748
Class<?> toType = cast.toType();
@@ -744,6 +762,11 @@ private void emitCast(Cast cast) {
744762
case INT_TO_BYTE -> cb.i2b();
745763
case INT_TO_CHAR -> cb.i2c();
746764
case INT_TO_SHORT -> cb.i2s();
765+
case BYTE_TO_LONG, CHAR_TO_LONG, SHORT_TO_LONG, INT_TO_LONG -> cb.i2l();
766+
case LONG_TO_BYTE -> { cb.l2i(); cb.i2b(); }
767+
case LONG_TO_SHORT -> { cb.l2i(); cb.i2s(); }
768+
case LONG_TO_CHAR -> { cb.l2i(); cb.i2c(); }
769+
case LONG_TO_INT -> cb.l2i();
747770
case BOOLEAN_TO_INT, BYTE_TO_INT, CHAR_TO_INT, SHORT_TO_INT -> {
748771
// no-op in bytecode
749772
}

src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequenceBuilder.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import jdk.internal.foreign.abi.Binding.Cast;
3333
import jdk.internal.foreign.abi.Binding.Copy;
3434
import jdk.internal.foreign.abi.Binding.Dup;
35+
import jdk.internal.foreign.abi.Binding.ShiftLeft;
36+
import jdk.internal.foreign.abi.Binding.ShiftRight;
3537
import jdk.internal.foreign.abi.Binding.UnboxAddress;
3638
import jdk.internal.foreign.abi.Binding.VMLoad;
3739
import jdk.internal.foreign.abi.Binding.VMStore;
@@ -220,6 +222,8 @@ static boolean isUnbox(Binding binding) {
220222
case Copy unused -> true;
221223
case UnboxAddress unused -> true;
222224
case Dup unused -> true;
225+
case ShiftLeft unused -> true;
226+
case ShiftRight unused -> true;
223227
case Cast unused -> true;
224228

225229
case VMLoad unused -> false;
@@ -254,6 +258,8 @@ static boolean isBox(Binding binding) {
254258
case Allocate unused -> true;
255259
case BoxAddress unused -> true;
256260
case Dup unused -> true;
261+
case ShiftLeft unused -> true;
262+
case ShiftRight unused -> true;
257263
case Cast unused -> true;
258264

259265
case VMStore unused -> false;

src/java.base/share/classes/jdk/internal/foreign/abi/SharedUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker;
3434
import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker;
3535
import jdk.internal.foreign.abi.fallback.FallbackLinker;
36+
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64Linker;
3637
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker;
3738
import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker;
3839
import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker;
@@ -241,6 +242,7 @@ public static Linker getSystemLinker() {
241242
case LINUX_AARCH_64 -> LinuxAArch64Linker.getInstance();
242243
case MAC_OS_AARCH_64 -> MacOsAArch64Linker.getInstance();
243244
case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance();
245+
case LINUX_PPC_64 -> LinuxPPC64Linker.getInstance();
244246
case LINUX_PPC_64_LE -> LinuxPPC64leLinker.getInstance();
245247
case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance();
246248
case LINUX_S390 -> LinuxS390Linker.getInstance();
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2023 SAP SE. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
package jdk.internal.foreign.abi.ppc64;
27+
28+
/**
29+
* PPC64 CallArranger specialized for ABI v1.
30+
*/
31+
public class ABIv1CallArranger extends CallArranger {
32+
33+
@Override
34+
protected boolean useABIv2() {
35+
return false;
36+
}
37+
}

src/java.base/share/classes/jdk/internal/foreign/abi/ppc64/ABIv2CallArranger.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
*/
2626
package jdk.internal.foreign.abi.ppc64;
2727

28-
import jdk.internal.foreign.abi.ppc64.CallArranger;
29-
3028
/**
3129
* PPC64 CallArranger specialized for ABI v2.
3230
*/
3331
public class ABIv2CallArranger extends CallArranger {
34-
// Currently no specific content, but CallArranger detects usage of ABIv2 for this class.
32+
33+
@Override
34+
protected boolean useABIv2() {
35+
return true;
36+
}
3537
}

0 commit comments

Comments
 (0)