diff a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java
--- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java
+++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/abi/SharedUtils.java
@@ -43,10 +43,11 @@
 
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.VarHandle;
+import java.nio.ByteOrder;
 import java.util.List;
 import java.util.function.Consumer;
 import java.util.stream.IntStream;
 
 import static java.lang.invoke.MethodHandles.collectArguments;
@@ -60,10 +61,18 @@
 
     private static final MethodHandle MH_ALLOC_BUFFER;
     private static final MethodHandle MH_BASEADDRESS;
     private static final MethodHandle MH_BUFFER_COPY;
 
+    private static final VarHandle VH_BYTE = MemoryHandles.varHandle(byte.class, ByteOrder.nativeOrder());
+    private static final VarHandle VH_CHAR = MemoryHandles.varHandle(char.class, ByteOrder.nativeOrder());
+    private static final VarHandle VH_SHORT = MemoryHandles.varHandle(short.class, ByteOrder.nativeOrder());
+    private static final VarHandle VH_INT = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder());
+    private static final VarHandle VH_LONG = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
+    private static final VarHandle VH_FLOAT = MemoryHandles.varHandle(float.class, ByteOrder.nativeOrder());
+    private static final VarHandle VH_DOUBLE = MemoryHandles.varHandle(double.class, ByteOrder.nativeOrder());
+
     static {
         try {
             var lookup = MethodHandles.lookup();
             MH_ALLOC_BUFFER = lookup.findStatic(SharedUtils.class, "allocateNative",
                     methodType(MemorySegment.class, MemoryLayout.class));
@@ -310,10 +319,17 @@
             }
         }
         return handle;
     }
 
+    static void checkType(Class<?> actualType, Class<?> expectedType) {
+        if (expectedType != actualType) {
+            throw new IllegalArgumentException(
+                    String.format("Invalid operand type: %s. %s expected", actualType, expectedType));
+        }
+    }
+
     public static class SimpleVaArg {
         public final Class<?> carrier;
         public final MemoryLayout layout;
         public final Object value;
 
@@ -390,6 +406,67 @@
         @Override
         public MemoryAddress address() {
             return address;
         }
     }
+
+    static void writeOverSized(MemoryAddress ptr, Class<?> type, Object o) {
+        // use VH_LONG for integers to zero out the whole register in the process
+        if (type == long.class) {
+            VH_LONG.set(ptr, (long) o);
+        } else if (type == int.class) {
+            VH_LONG.set(ptr, (long) (int) o);
+        } else if (type == short.class) {
+            VH_LONG.set(ptr, (long) (short) o);
+        } else if (type == char.class) {
+            VH_LONG.set(ptr, (long) (char) o);
+        } else if (type == byte.class) {
+            VH_LONG.set(ptr, (long) (byte) o);
+        } else if (type == float.class) {
+            VH_FLOAT.set(ptr, (float) o);
+        } else if (type == double.class) {
+            VH_DOUBLE.set(ptr, (double) o);
+        } else {
+            throw new IllegalArgumentException("Unsupported carrier: " + type);
+        }
+    }
+
+    static void write(MemoryAddress ptr, Class<?> type, Object o) {
+        if (type == long.class) {
+            VH_LONG.set(ptr, (long) o);
+        } else if (type == int.class) {
+            VH_INT.set(ptr, (int) o);
+        } else if (type == short.class) {
+            VH_SHORT.set(ptr, (short) o);
+        } else if (type == char.class) {
+            VH_CHAR.set(ptr, (char) o);
+        } else if (type == byte.class) {
+            VH_BYTE.set(ptr, (byte) o);
+        } else if (type == float.class) {
+            VH_FLOAT.set(ptr, (float) o);
+        } else if (type == double.class) {
+            VH_DOUBLE.set(ptr, (double) o);
+        } else {
+            throw new IllegalArgumentException("Unsupported carrier: " + type);
+        }
+    }
+
+    static Object read(MemoryAddress ptr, Class<?> type) {
+        if (type == long.class) {
+            return (long) VH_LONG.get(ptr);
+        } else if (type == int.class) {
+            return (int) VH_INT.get(ptr);
+        } else if (type == short.class) {
+            return (short) VH_SHORT.get(ptr);
+        } else if (type == char.class) {
+            return (char) VH_CHAR.get(ptr);
+        } else if (type == byte.class) {
+            return (byte) VH_BYTE.get(ptr);
+        } else if (type == float.class) {
+            return (float) VH_FLOAT.get(ptr);
+        } else if (type == double.class) {
+            return (double) VH_DOUBLE.get(ptr);
+        } else {
+            throw new IllegalArgumentException("Unsupported carrier: " + type);
+        }
+    }
 }
