< prev index next >

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

Print this page

        

@@ -22,12 +22,149 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 package jdk.internal.foreign.abi.x64;
 
-public class SharedConstants {
+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 >