< prev index next >

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

Print this page

        

*** 22,33 **** * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.internal.foreign.abi.x64; ! public class SharedConstants { public static final int INTEGER_REGISTER_SIZE = 8; public static final int VECTOR_REGISTER_SIZE = 64; // (maximum) vector size is 512 bits public static final int X87_REGISTER_SIZE = 16; // x87 register is 128 bits public static final int STACK_SLOT_SIZE = 8; } --- 22,170 ---- * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.internal.foreign.abi.x64; ! import jdk.internal.foreign.abi.Storage; ! ! import java.foreign.layout.Address; ! import java.foreign.layout.Group; ! import java.foreign.layout.Layout; ! import java.foreign.layout.Padding; ! import java.foreign.layout.Sequence; ! import java.foreign.layout.Value; ! ! public class SharedUtils { public static final int INTEGER_REGISTER_SIZE = 8; public static final int VECTOR_REGISTER_SIZE = 64; // (maximum) vector size is 512 bits public static final int X87_REGISTER_SIZE = 16; // x87 register is 128 bits public static final int STACK_SLOT_SIZE = 8; + + /** + * Align the specified type from a given address + * @return The address the data should be at based on alignment requirement + */ + public static long align(Layout t, boolean isVar, long addr) { + return alignUp(addr, alignment(t, isVar)); + } + + public static long alignUp(long addr, long alignment) { + return ((addr - 1) | (alignment - 1)) + 1; + } + + public static long alignDown(long addr, long alignment) { + return addr & ~(alignment - 1); + } + + /** + * The alignment requirement for a given type + * @param isVar indicate if the type is a standalone variable. This change how + * array is aligned. for example. + */ + public static long alignment(Layout t, boolean isVar) { + if (t instanceof Value) { + return alignmentOfScalar((Value) t); + } else if (t instanceof Sequence) { + // when array is used alone + return alignmentOfArray((Sequence) t, isVar); + } else if (t instanceof Group) { + return alignmentOfContainer((Group) t); + } else if (t instanceof Address) { + return 8; + } else if (t instanceof Padding) { + return 1; + } else { + throw new IllegalArgumentException("Invalid type: " + t); + } + } + + private static long alignmentOfScalar(Value st) { + return st.bitsSize() / 8; + } + + private static long alignmentOfArray(Sequence ar, boolean isVar) { + if (ar.elementsSize() == 0) { + // VLA or incomplete + return 16; + } else if ((ar.bitsSize() / 8) >= 16 && isVar) { + return 16; + } else { + // align as element type + Layout elementType = ar.element(); + return alignment(elementType, false); + } + } + + private static long alignmentOfContainer(Group ct) { + // Most strict member + return ct.elements().stream().mapToLong(t -> alignment(t, false)).max().orElse(1); + } + + public static class StorageDebugHelper { + + private final String[] integerArgumentRegisterNames; + private final String[] integerReturnRegisterNames; + private final String[] x87ReturnRegisterNames; + private final int maxVectorArgRegisters; + private final int maxVectorReturnRegisters; + + public StorageDebugHelper(String[] integerArgumentRegisterNames, String[] integerReturnRegisterNames, + String[] x87ReturnRegisterNames, int maxVectorArgRegisters, int maxVectorReturnRegisters) { + this.integerArgumentRegisterNames = integerArgumentRegisterNames; + this.integerReturnRegisterNames = integerReturnRegisterNames; + this.x87ReturnRegisterNames = x87ReturnRegisterNames; + this.maxVectorArgRegisters = maxVectorArgRegisters; + this.maxVectorReturnRegisters = maxVectorReturnRegisters; + } + + + private static String getVectorRegisterName(long index, long size) { + switch ((int)size) { + case 8: return "xmm" + index + "_8"; + case 16: return "xmm" + index; + case 32: return "ymm" + index; + case 64: return "zmm" + index; + default: throw new IllegalArgumentException("Illegal vector size: " + size); + } + } + + public String getStorageName(Storage storage) { + switch (storage.getStorageClass()) { + case INTEGER_ARGUMENT_REGISTER: + if (storage.getStorageIndex() > integerArgumentRegisterNames.length) { + throw new IllegalArgumentException("Illegal storage: " + storage); + } + return integerArgumentRegisterNames[(int) storage.getStorageIndex()]; + + case VECTOR_ARGUMENT_REGISTER: + if (storage.getStorageIndex() > maxVectorArgRegisters) { + throw new IllegalArgumentException("Illegal storage: " + storage); + } + return getVectorRegisterName(storage.getStorageIndex(), storage.getSize()); + + case INTEGER_RETURN_REGISTER: + if (storage.getStorageIndex() > integerReturnRegisterNames.length) { + throw new IllegalArgumentException("Illegal storage: " + storage); + } + + return integerReturnRegisterNames[(int) storage.getStorageIndex()]; + + case VECTOR_RETURN_REGISTER: + if (storage.getStorageIndex() > maxVectorReturnRegisters) { + throw new IllegalArgumentException("Illegal storage: " + storage); + } + return getVectorRegisterName(storage.getStorageIndex(), storage.getSize()); + + case X87_RETURN_REGISTER: + if (storage.getStorageIndex() > x87ReturnRegisterNames.length) { + throw new IllegalArgumentException("Illegal storage: " + storage); + } + return x87ReturnRegisterNames[(int) storage.getStorageIndex()]; + + case STACK_ARGUMENT_SLOT: return "[sp + " + Long.toHexString(8 * storage.getStorageIndex()) + "]"; + } + + throw new IllegalArgumentException("Unhandled storage type: " + storage.getStorageClass()); + } + } }
< prev index next >