Skip to content

Commit

Permalink
8314949: linux PPC64 Big Endian: Implementation of Foreign Function &…
Browse files Browse the repository at this point in the history
… Memory API

Reviewed-by: mcimadamore, jvernee
  • Loading branch information
TheRealMDoerr committed Sep 6, 2023
1 parent a01b3fb commit f6c203e
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/cpu/ppc/foreignGlobals_ppc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ bool ABIDescriptor::is_volatile_reg(FloatRegister reg) const {
}

bool ForeignGlobals::is_foreign_linker_supported() {
#ifdef ABI_ELFv2
#ifdef LINUX
return true;
#else
return false;
Expand Down
5 changes: 5 additions & 0 deletions src/java.base/share/classes/jdk/internal/foreign/CABI.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public enum CABI {
LINUX_AARCH_64,
MAC_OS_AARCH_64,
WIN_AARCH_64,
LINUX_PPC_64,
LINUX_PPC_64_LE,
LINUX_RISCV_64,
LINUX_S390,
Expand Down Expand Up @@ -74,6 +75,10 @@ private static CABI computeCurrent() {
// The Linux ABI follows the standard AAPCS ABI
return LINUX_AARCH_64;
}
} else if (arch.equals("ppc64")) {
if (OperatingSystem.isLinux()) {
return LINUX_PPC_64;
}
} else if (arch.equals("ppc64le")) {
if (OperatingSystem.isLinux()) {
return LINUX_PPC_64_LE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker;
import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker;
import jdk.internal.foreign.abi.fallback.FallbackLinker;
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64Linker;
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker;
import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker;
import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker;
Expand Down Expand Up @@ -60,7 +61,8 @@

public abstract sealed class AbstractLinker implements Linker permits LinuxAArch64Linker, MacOsAArch64Linker,
SysVx64Linker, WindowsAArch64Linker,
Windowsx64Linker, LinuxPPC64leLinker,
Windowsx64Linker,
LinuxPPC64Linker, LinuxPPC64leLinker,
LinuxRISCV64Linker, LinuxS390Linker,
FallbackLinker {

Expand Down
109 changes: 108 additions & 1 deletion src/java.base/share/classes/jdk/internal/foreign/abi/Binding.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,18 @@ static Dup dup() {
return Dup.INSTANCE;
}

static ShiftLeft shiftLeft(int shiftAmount) {
if (shiftAmount <= 0)
throw new IllegalArgumentException("shiftAmount must be positive");
return new ShiftLeft(shiftAmount);
}

static ShiftRight shiftRight(int shiftAmount) {
if (shiftAmount <= 0)
throw new IllegalArgumentException("shiftAmount must be positive");
return new ShiftRight(shiftAmount);
}

static Binding cast(Class<?> fromType, Class<?> toType) {
if (fromType == int.class) {
if (toType == boolean.class) {
Expand All @@ -286,6 +298,8 @@ static Binding cast(Class<?> fromType, Class<?> toType) {
return Cast.INT_TO_SHORT;
} else if (toType == char.class) {
return Cast.INT_TO_CHAR;
} else if (toType == long.class) {
return Cast.INT_TO_LONG;
}
} else if (toType == int.class) {
if (fromType == boolean.class) {
Expand All @@ -296,6 +310,24 @@ static Binding cast(Class<?> fromType, Class<?> toType) {
return Cast.SHORT_TO_INT;
} else if (fromType == char.class) {
return Cast.CHAR_TO_INT;
} else if (fromType == long.class) {
return Cast.LONG_TO_INT;
}
} else if (fromType == long.class) {
if (toType == byte.class) {
return Cast.LONG_TO_BYTE;
} else if (toType == short.class) {
return Cast.LONG_TO_SHORT;
} else if (toType == char.class) {
return Cast.LONG_TO_CHAR;
}
} else if (toType == long.class) {
if (fromType == byte.class) {
return Cast.BYTE_TO_LONG;
} else if (fromType == short.class) {
return Cast.SHORT_TO_LONG;
} else if (fromType == char.class) {
return Cast.CHAR_TO_LONG;
}
}
throw new IllegalArgumentException("Unknown conversion: " + fromType + " -> " + toType);
Expand Down Expand Up @@ -387,6 +419,24 @@ public Binding.Builder dup() {
return this;
}

// Converts to long if needed then shifts left by the given number of Bytes.
public Binding.Builder shiftLeft(int shiftAmount, Class<?> type) {
if (type != long.class) {
bindings.add(Binding.cast(type, long.class));
}
bindings.add(Binding.shiftLeft(shiftAmount));
return this;
}

// Shifts right by the given number of Bytes then converts from long if needed.
public Binding.Builder shiftRight(int shiftAmount, Class<?> type) {
bindings.add(Binding.shiftRight(shiftAmount));
if (type != long.class) {
bindings.add(Binding.cast(long.class, type));
}
return this;
}

public List<Binding> build() {
return List.copyOf(bindings);
}
Expand Down Expand Up @@ -670,6 +720,52 @@ public void interpret(Deque<Object> stack, StoreFunc storeFunc,
}
}

/**
* ShiftLeft([shiftAmount])
* Shifts the Bytes on the top of the operand stack (64 bit unsigned).
* Shifts left by the given number of Bytes.
*/
record ShiftLeft(int shiftAmount) implements Binding {

@Override
public void verify(Deque<Class<?>> stack) {
Class<?> last = stack.pop();
SharedUtils.checkType(last, long.class);
stack.push(long.class);
}

@Override
public void interpret(Deque<Object> stack, StoreFunc storeFunc,
LoadFunc loadFunc, SegmentAllocator allocator) {
long l = (long) stack.pop();
l <<= (shiftAmount * Byte.SIZE);
stack.push(l);
}
}

/**
* ShiftRight([shiftAmount])
* Shifts the Bytes on the top of the operand stack (64 bit unsigned).
* Shifts right by the given number of Bytes.
*/
record ShiftRight(int shiftAmount) implements Binding {

@Override
public void verify(Deque<Class<?>> stack) {
Class<?> last = stack.pop();
SharedUtils.checkType(last, long.class);
stack.push(long.class);
}

@Override
public void interpret(Deque<Object> stack, StoreFunc storeFunc,
LoadFunc loadFunc, SegmentAllocator allocator) {
long l = (long) stack.pop();
l >>>= (shiftAmount * Byte.SIZE);
stack.push(l);
}
}

/**
* CAST([fromType], [toType])
* Pop a [fromType] from the stack, convert it to [toType], and push the resulting
Expand All @@ -690,10 +786,21 @@ public void interpret(Deque<Object> stack, StoreFunc storeFunc,
INT_TO_BYTE(int.class, byte.class),
INT_TO_CHAR(int.class, char.class),
INT_TO_SHORT(int.class, short.class),
INT_TO_LONG(int.class, long.class),

BOOLEAN_TO_INT(boolean.class, int.class),
BYTE_TO_INT(byte.class, int.class),
CHAR_TO_INT(char.class, int.class),
SHORT_TO_INT(short.class, int.class);
SHORT_TO_INT(short.class, int.class),
LONG_TO_INT(long.class, int.class),

LONG_TO_BYTE(long.class, byte.class),
LONG_TO_SHORT(long.class, short.class),
LONG_TO_CHAR(long.class, char.class),

BYTE_TO_LONG(byte.class, long.class),
SHORT_TO_LONG(short.class, long.class),
CHAR_TO_LONG(char.class, long.class);

private final Class<?> fromType;
private final Class<?> toType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import jdk.internal.foreign.abi.Binding.Cast;
import jdk.internal.foreign.abi.Binding.Copy;
import jdk.internal.foreign.abi.Binding.Dup;
import jdk.internal.foreign.abi.Binding.ShiftLeft;
import jdk.internal.foreign.abi.Binding.ShiftRight;
import jdk.internal.foreign.abi.Binding.UnboxAddress;
import jdk.internal.foreign.abi.Binding.VMLoad;
import jdk.internal.foreign.abi.Binding.VMStore;
Expand Down Expand Up @@ -463,6 +465,8 @@ private void doBindings(List<Binding> bindings) {
case BoxAddress boxAddress -> emitBoxAddress(boxAddress);
case UnboxAddress unused -> emitUnboxAddress();
case Dup unused -> emitDupBinding();
case ShiftLeft shiftLeft -> emitShiftLeft(shiftLeft);
case ShiftRight shiftRight -> emitShiftRight(shiftRight);
case Cast cast -> emitCast(cast);
}
}
Expand Down Expand Up @@ -725,6 +729,20 @@ private void emitDupBinding() {
pushType(dupType);
}

private void emitShiftLeft(ShiftLeft shiftLeft) {
popType(long.class);
cb.constantInstruction(shiftLeft.shiftAmount() * Byte.SIZE);
cb.lshl();
pushType(long.class);
}

private void emitShiftRight(ShiftRight shiftRight) {
popType(long.class);
cb.constantInstruction(shiftRight.shiftAmount() * Byte.SIZE);
cb.lushr();
pushType(long.class);
}

private void emitCast(Cast cast) {
Class<?> fromType = cast.fromType();
Class<?> toType = cast.toType();
Expand All @@ -744,6 +762,11 @@ private void emitCast(Cast cast) {
case INT_TO_BYTE -> cb.i2b();
case INT_TO_CHAR -> cb.i2c();
case INT_TO_SHORT -> cb.i2s();
case BYTE_TO_LONG, CHAR_TO_LONG, SHORT_TO_LONG, INT_TO_LONG -> cb.i2l();
case LONG_TO_BYTE -> { cb.l2i(); cb.i2b(); }
case LONG_TO_SHORT -> { cb.l2i(); cb.i2s(); }
case LONG_TO_CHAR -> { cb.l2i(); cb.i2c(); }
case LONG_TO_INT -> cb.l2i();
case BOOLEAN_TO_INT, BYTE_TO_INT, CHAR_TO_INT, SHORT_TO_INT -> {
// no-op in bytecode
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import jdk.internal.foreign.abi.Binding.Cast;
import jdk.internal.foreign.abi.Binding.Copy;
import jdk.internal.foreign.abi.Binding.Dup;
import jdk.internal.foreign.abi.Binding.ShiftLeft;
import jdk.internal.foreign.abi.Binding.ShiftRight;
import jdk.internal.foreign.abi.Binding.UnboxAddress;
import jdk.internal.foreign.abi.Binding.VMLoad;
import jdk.internal.foreign.abi.Binding.VMStore;
Expand Down Expand Up @@ -220,6 +222,8 @@ static boolean isUnbox(Binding binding) {
case Copy unused -> true;
case UnboxAddress unused -> true;
case Dup unused -> true;
case ShiftLeft unused -> true;
case ShiftRight unused -> true;
case Cast unused -> true;

case VMLoad unused -> false;
Expand Down Expand Up @@ -254,6 +258,8 @@ static boolean isBox(Binding binding) {
case Allocate unused -> true;
case BoxAddress unused -> true;
case Dup unused -> true;
case ShiftLeft unused -> true;
case ShiftRight unused -> true;
case Cast unused -> true;

case VMStore unused -> false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import jdk.internal.foreign.abi.aarch64.macos.MacOsAArch64Linker;
import jdk.internal.foreign.abi.aarch64.windows.WindowsAArch64Linker;
import jdk.internal.foreign.abi.fallback.FallbackLinker;
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64Linker;
import jdk.internal.foreign.abi.ppc64.linux.LinuxPPC64leLinker;
import jdk.internal.foreign.abi.riscv64.linux.LinuxRISCV64Linker;
import jdk.internal.foreign.abi.s390.linux.LinuxS390Linker;
Expand Down Expand Up @@ -241,6 +242,7 @@ public static Linker getSystemLinker() {
case LINUX_AARCH_64 -> LinuxAArch64Linker.getInstance();
case MAC_OS_AARCH_64 -> MacOsAArch64Linker.getInstance();
case WIN_AARCH_64 -> WindowsAArch64Linker.getInstance();
case LINUX_PPC_64 -> LinuxPPC64Linker.getInstance();
case LINUX_PPC_64_LE -> LinuxPPC64leLinker.getInstance();
case LINUX_RISCV_64 -> LinuxRISCV64Linker.getInstance();
case LINUX_S390 -> LinuxS390Linker.getInstance();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2023 SAP SE. 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 jdk.internal.foreign.abi.ppc64;

/**
* PPC64 CallArranger specialized for ABI v1.
*/
public class ABIv1CallArranger extends CallArranger {

@Override
protected boolean useABIv2() {
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
*/
package jdk.internal.foreign.abi.ppc64;

import jdk.internal.foreign.abi.ppc64.CallArranger;

/**
* PPC64 CallArranger specialized for ABI v2.
*/
public class ABIv2CallArranger extends CallArranger {
// Currently no specific content, but CallArranger detects usage of ABIv2 for this class.

@Override
protected boolean useABIv2() {
return true;
}
}

1 comment on commit f6c203e

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.