[Vm-dev] [commit][3400] CogVM source as per VMMaker.oscog-eem.1408

commits at squeakvm.org commits at squeakvm.org
Wed Jul 8 18:28:32 UTC 2015


Revision: 3400
Author:   eliot
Date:     2015-07-08 11:28:29 -0700 (Wed, 08 Jul 2015)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1408

ThreadedFFIPlugin:
Allow ffiCreateIntegralResultOop:ofAtomicType:in: to be inlined.  Reduce the
number of tests leading to the common case of an integral return in
ffiCalloutTo:SpecOnStack:in: etc.

Refactor the remapOop:in: idiom up into InterpreterPlugin and use it in the
ThreadedFFIPlugin.

Use an official version of MiscPrimitivePlugin.c in Newspeak (no change).

Modified Paths:
--------------
    branches/Cog/nsspursrc/plugins/MiscPrimitivePlugin/MiscPrimitivePlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/IA32FFIPlugin.c

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/nsspursrc/plugins/MiscPrimitivePlugin/MiscPrimitivePlugin.c
===================================================================
--- branches/Cog/nsspursrc/plugins/MiscPrimitivePlugin/MiscPrimitivePlugin.c	2015-07-07 20:53:26 UTC (rev 3399)
+++ branches/Cog/nsspursrc/plugins/MiscPrimitivePlugin/MiscPrimitivePlugin.c	2015-07-08 18:28:29 UTC (rev 3400)
@@ -1,16 +1,16 @@
 /* Automatically generated by
-	VMPluginCodeGenerator * VMMaker.oscog-cb.1379 uuid: cc44db6e-5fe4-4aee-9a1b-e6de870b83a8
+	VMPluginCodeGenerator VMMaker.oscog-eem.1325 uuid: a0bb0f7f-5e6e-48a7-bf73-fa5d135e06c0
    from
-	MiscPrimitivePlugin * VMMaker.oscog-cb.1379 uuid: cc44db6e-5fe4-4aee-9a1b-e6de870b83a8
+	MiscPrimitivePlugin VMMaker.oscog-eem.1325 uuid: a0bb0f7f-5e6e-48a7-bf73-fa5d135e06c0
 	Bitmap * Graphics-mt.313 uuid: 99af1adc-65b3-5549-8d10-ab452e0c59e5
-	ByteArray * Collections.spur-eem.636 uuid: b341b330-e1ef-455e-9880-7b782cc4f014
-	ByteString * Collections.spur-eem.636 uuid: b341b330-e1ef-455e-9880-7b782cc4f014
+	ByteArray * Collections.spur-ul.610, Collections.spur-ul.627, Collections.spur-mt.631, Collections.spur-mt.635 uuid: 3448b17a-1361-47a8-af38-4c26b42dc028
+	ByteString * Collections.spur-ul.610, Collections.spur-ul.627, Collections.spur-mt.631, Collections.spur-mt.635 uuid: 3448b17a-1361-47a8-af38-4c26b42dc028
 	SampledSound Sound-topa.43 uuid: c1c2b948-6c86-4cf8-877d-1620433f558e
  */
-static char __buildInfo[] = "MiscPrimitivePlugin * VMMaker.oscog-cb.1379 uuid: cc44db6e-5fe4-4aee-9a1b-e6de870b83a8\n\
+static char __buildInfo[] = "MiscPrimitivePlugin VMMaker.oscog-eem.1325 uuid: a0bb0f7f-5e6e-48a7-bf73-fa5d135e06c0\n\
 Bitmap * Graphics-mt.313 uuid: 99af1adc-65b3-5549-8d10-ab452e0c59e5\n\
-ByteArray * Collections.spur-eem.636 uuid: b341b330-e1ef-455e-9880-7b782cc4f014\n\
-ByteString * Collections.spur-eem.636 uuid: b341b330-e1ef-455e-9880-7b782cc4f014\n\
+ByteArray * Collections.spur-ul.610, Collections.spur-ul.627, Collections.spur-mt.631, Collections.spur-mt.635 uuid: 3448b17a-1361-47a8-af38-4c26b42dc028\n\
+ByteString * Collections.spur-ul.610, Collections.spur-ul.627, Collections.spur-mt.631, Collections.spur-mt.635 uuid: 3448b17a-1361-47a8-af38-4c26b42dc028\n\
 SampledSound Sound-topa.43 uuid: c1c2b948-6c86-4cf8-877d-1620433f558e " __DATE__ ;
 
 
@@ -90,9 +90,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"MiscPrimitivePlugin * VMMaker.oscog-cb.1379 (i)"
+	"MiscPrimitivePlugin VMMaker.oscog-eem.1325 (i)"
 #else
-	"MiscPrimitivePlugin * VMMaker.oscog-cb.1379 (e)"
+	"MiscPrimitivePlugin VMMaker.oscog-eem.1325 (e)"
 #endif
 ;
 


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Tue Jul  7 13:52:43 PDT 2015
   + Wed Jul  8 11:27:26 PDT 2015

Modified: branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
===================================================================
--- branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c	2015-07-07 20:53:26 UTC (rev 3399)
+++ branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c	2015-07-08 18:28:29 UTC (rev 3400)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	VMPluginCodeGenerator VMMaker.oscog-eem.1359 uuid: 0e62a222-6136-430f-9bc2-8e7cee245076
+	VMPluginCodeGenerator VMMaker.oscog-eem.1408 uuid: 51bc4e0f-a338-4394-8c6a-22b4b3e07c61
    from
-	ThreadedARMFFIPlugin VMMaker.oscog-eem.1359 uuid: 0e62a222-6136-430f-9bc2-8e7cee245076
+	ThreadedARMFFIPlugin VMMaker.oscog-eem.1408 uuid: 51bc4e0f-a338-4394-8c6a-22b4b3e07c61
  */
-static char __buildInfo[] = "ThreadedARMFFIPlugin VMMaker.oscog-eem.1359 uuid: 0e62a222-6136-430f-9bc2-8e7cee245076 " __DATE__ ;
+static char __buildInfo[] = "ThreadedARMFFIPlugin VMMaker.oscog-eem.1408 uuid: 51bc4e0f-a338-4394-8c6a-22b4b3e07c61 " __DATE__ ;
 
 
 
@@ -454,9 +454,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"ARM32FFIPlugin VMMaker.oscog-eem.1359 (i)"
+	"ARM32FFIPlugin VMMaker.oscog-eem.1408 (i)"
 #else
-	"ARM32FFIPlugin VMMaker.oscog-eem.1359 (e)"
+	"ARM32FFIPlugin VMMaker.oscog-eem.1408 (e)"
 #endif
 ;
 
@@ -1567,6 +1567,7 @@
     sqInt argTypes1;
     sqInt atomicType;
     sqInt atomicType1;
+    sqInt byteSize;
     sqInt classOop;
     sqInt cPointer;
     char *cString;
@@ -1574,15 +1575,19 @@
     double floatRet;
     sqInt i;
     usqLong intRet;
+    extern void loadFloatRegs(double, double, double, double, double, double, double, double);
+    sqInt mask;
     sqInt myThreadIndex;
     sqInt oop;
     sqInt oop1;
+    sqInt oop2;
     sqInt *ptr;
     sqInt retClass;
     sqInt retClass1;
     sqInt retOop;
     sqInt retOop1;
     sqInt retType;
+    sqInt shift;
     sqInt specLiteral;
     sqInt specLiteral1;
     sqInt strLen;
@@ -1590,11 +1595,13 @@
     char *strPtr;
     sqInt typeSpec;
     sqInt typeSpec1;
+    usqLong value;
 
 	floatRet = 0;
 	intRet = 0;
 	myThreadIndex = 0;
 	
+	
 #  if COGMTVM
 	if (((calloutState->callFlags)) & FFICallFlagThreaded) {
 		myThreadIndex = disownVM(0);
@@ -1611,12 +1618,17 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if (atomicType == FFITypeSingleFloat) {
-		floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if (atomicType == FFITypeSingleFloat) {
+			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+		}
+		else {
+
+			/* atomicType = FFITypeDoubleFloat */
+
+			floatRet = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+		}
 	}
-	if (atomicType == FFITypeDoubleFloat) {
-		floatRet = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
-	}
 	else {
 		intRet = dispatchFunctionPointerwithwithwithwith(((usqLong (*)(int, int, int, int)) procAddr), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 	}
@@ -1631,108 +1643,198 @@
 
 #  endif /* COGMTVM */
 
-	if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
-		/* begin ffiReturnPointer:ofType:in: */
-		/* begin ffiReturnType: */
-		specLiteral1 = (specOnStack
-			? stackValue(1)
-			: literalofMethod(0, primitiveMethod()));
-		argTypes1 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
-		retType = fetchPointerofObject(0, argTypes1);
-		retClass1 = fetchPointerofObject(1, retType);
-		if (retClass1 == (nilObject())) {
+	if (((calloutState->ffiRetHeader)) & (FFIFlagPointer + FFIFlagStructure)) {
 
-			/* Create ExternalData upon return */
+		/* Note: Order is important here since FFIFlagPointer + FFIFlagStructure is used to represent
+		   'typedef void* VoidPointer' and VoidPointer must be returned as pointer *not* as struct. */
 
-			/* begin atomicTypeOf: */
-			typeSpec1 = (calloutState->ffiRetHeader);
-			atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-			if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+		return (((calloutState->ffiRetHeader)) & FFIFlagPointer
+			? (/* begin ffiReturnPointer:ofType:in: */
+				/* begin ffiReturnType: */
+				(specLiteral1 = (specOnStack
+						? stackValue(1)
+						: literalofMethod(0, primitiveMethod()))),
+				(argTypes1 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1)),
+				(retType = fetchPointerofObject(0, argTypes1)),
+				(retClass1 = fetchPointerofObject(1, retType)),
+				(retClass1 == (nilObject())
+						? (/* begin atomicTypeOf: */
+							(typeSpec1 = (calloutState->ffiRetHeader)),
+							(atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift),
+							((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)
+									? (/* begin ffiReturnCStringFrom: */
+										(cPointer = ((usqInt) intRet)),
+										(cPointer == null
+												? (methodReturnValue(nilObject()),
+													goto l2)
+												: 0),
+										(cString = ((char *) cPointer)),
+										(strLen = 0),
+										while (!((cString[strLen]) == 0)) {
+												strLen += 1;
+											}
+										(strOop = instantiateClassindexableSize(classString(), strLen)),
+										(strPtr = firstIndexableField(strOop)),
+										for (i = 0; i < strLen; i += 1) {
+												strPtr[i] = (cString[i]);
+											}
+										methodReturnValue(strOop),
+										goto l2)
+									: 0),
+							
+#if SPURVM
+								oop2 = instantiateClassindexableSize(classExternalAddress(), 4);
+								ptr = firstIndexableField(oop2);
+								ptr[0] = (((sqInt) intRet));
+								
+#if SPURVM
+								retOop1 = instantiateClassindexableSize(classExternalData(), 0);
 
-				/* String return */
+#else /* SPURVM */
+								pushRemappableOop(oop2);
+								retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+								oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+								storePointerofObjectwithValue(0, retOop1, oop2);
 
-				/* begin ffiReturnCStringFrom: */
-				cPointer = ((usqInt) intRet);
-				if (cPointer == null) {
-					return methodReturnValue(nilObject());
-				}
-				cString = ((char *) cPointer);
-				strLen = 0;
-				while (!((cString[strLen]) == 0)) {
-					strLen += 1;
-				}
-				strOop = instantiateClassindexableSize(classString(), strLen);
-				strPtr = firstIndexableField(strOop);
-				for (i = 0; i < strLen; i += 1) {
-					strPtr[i] = (cString[i]);
-				}
-				return methodReturnValue(strOop);
-			}
-			pushRemappableOop(retType);
-			oop1 = instantiateClassindexableSize(classExternalAddress(), 4);
-			ptr = firstIndexableField(oop1);
-			ptr[0] = (((sqInt) intRet));
-			pushRemappableOop(oop1);
-			retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+#else /* SPURVM */
+								pushRemappableOop(retType);
+								oop2 = instantiateClassindexableSize(classExternalAddress(), 4);
+								ptr = firstIndexableField(oop2);
+								ptr[0] = (((sqInt) intRet));
+								
+#if SPURVM
+								retOop1 = instantiateClassindexableSize(classExternalData(), 0);
 
-			/* external address */
+#else /* SPURVM */
+								pushRemappableOop(oop2);
+								retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+								oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+								storePointerofObjectwithValue(0, retOop1, oop2);
+								retType = popRemappableOop()
+#endif /* SPURVM */
+,
+							storePointerofObjectwithValue(1, retOop1, retType),
+							methodReturnValue(retOop1),
+							goto l2)
+						: 0),
+				(classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
+						? classByteArray()
+						: classExternalAddress())),
+				
+#if SPURVM
+					oop2 = instantiateClassindexableSize(classOop, 4);
 
-			oop1 = popRemappableOop();
-			storePointerofObjectwithValue(0, retOop1, oop1);
+#else /* SPURVM */
+					pushRemappableOop(retClass1);
+					oop2 = instantiateClassindexableSize(classOop, 4);
+					retClass1 = popRemappableOop()
+#endif /* SPURVM */
+,
+				(ptr = firstIndexableField(oop2)),
+				ptr[0] = (((sqInt) intRet)),
+				
+#if SPURVM
+					retOop1 = instantiateClassindexableSize(retClass1, 0);
 
-			/* return type */
+#else /* SPURVM */
+					pushRemappableOop(oop2);
+					retOop1 = instantiateClassindexableSize(retClass1, 0);
+					oop2 = popRemappableOop()
+#endif /* SPURVM */
+,
+				storePointerofObjectwithValue(0, retOop1, oop2),
+				methodReturnValue(retOop1),
+			l2:	/* end ffiReturnPointer:ofType:in: */)
+			: (/* begin ffiReturnStruct:ofType:in: */
+				/* begin ffiReturnType: */
+				(specLiteral = (specOnStack
+						? stackValue(1)
+						: literalofMethod(0, primitiveMethod()))),
+				(argTypes = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral)),
+				(ffiRetType = fetchPointerofObject(0, argTypes)),
+				(retClass = fetchPointerofObject(1, ffiRetType)),
+				(retOop = instantiateClassindexableSize(retClass, 0)),
+				
+#if SPURVM
+					oop1 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
 
-			oop1 = popRemappableOop();
-			storePointerofObjectwithValue(1, retOop1, oop1);
-			return methodReturnValue(retOop1);
+#else /* SPURVM */
+					pushRemappableOop(retOop);
+					oop1 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
+					retOop = popRemappableOop()
+#endif /* SPURVM */
+,
+				(returnStructInRegisters((calloutState->structReturnSize))
+						? memcpy(firstIndexableField(oop1), (&intRet), (calloutState->structReturnSize))
+						: memcpy(firstIndexableField(oop1), (calloutState->limit), (calloutState->structReturnSize))),
+				storePointerofObjectwithValue(0, retOop, oop1),
+				methodReturnValue(retOop)));
+	}
+	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		oop = floatObjectOf(floatRet);
+	}
+	else {
+		/* begin ffiCreateIntegralResultOop:ofAtomicType:in: */
+		assert(atomicType < FFITypeSingleFloat);
+		if (atomicType == FFITypeBool) {
+
+			/* Make sure bool honors the byte size requested */
+
+			byteSize = ((calloutState->ffiRetHeader)) & FFIStructSizeMask;
+			value = (byteSize == (sizeof(intRet))
+				? intRet
+				: intRet & ((1 << (byteSize * 8)) - 1));
+			oop = (value == 0
+				? falseObject()
+				: trueObject());
+			goto l1;
 		}
-		pushRemappableOop(retClass1);
-		classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
-			? classByteArray()
-			: classExternalAddress());
-		oop1 = instantiateClassindexableSize(classOop, 4);
-		ptr = firstIndexableField(oop1);
-		ptr[0] = (((sqInt) intRet));
+		if (atomicType <= FFITypeSignedInt) {
 
-		/* return class */
+			/* these are all generall integer returns */
 
-		retClass1 = popRemappableOop();
-		pushRemappableOop(oop1);
-		retOop1 = instantiateClassindexableSize(retClass1, 0);
+			if (atomicType <= FFITypeSignedShort) {
 
-		/* external address */
+				/* byte/short. first extract partial word, then sign extend */
 
-		oop1 = popRemappableOop();
-		storePointerofObjectwithValue(0, retOop1, oop1);
-		return methodReturnValue(retOop1);
-	}
-	if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
-		/* begin ffiReturnStruct:ofType:in: */
-		/* begin ffiReturnType: */
-		specLiteral = (specOnStack
-			? stackValue(1)
-			: literalofMethod(0, primitiveMethod()));
-		argTypes = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
-		ffiRetType = fetchPointerofObject(0, argTypes);
-		retClass = fetchPointerofObject(1, ffiRetType);
-		retOop = instantiateClassindexableSize(retClass, 0);
-		pushRemappableOop(retOop);
-		oop = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
-		if (returnStructInRegisters((calloutState->structReturnSize))) {
-			memcpy(firstIndexableField(oop), (&intRet), (calloutState->structReturnSize));
+
+				/* # of significant bits */
+
+				shift = (((usqInt) atomicType) >> 1) * 8;
+				value = intRet & ((1 << shift) - 1);
+				if (atomicType & 1) {
+
+					/* make the guy signed */
+
+					mask = 1 << (shift - 1);
+					value = (value & (mask - 1)) - (value & mask);
+				}
+				oop = integerObjectOf(value);
+				goto l1;
+			}
+			oop = (atomicType & 1
+				? signed32BitIntegerFor(intRet)
+				: positive32BitIntegerFor(intRet));
+			goto l1;
 		}
-		else {
-			memcpy(firstIndexableField(oop), (calloutState->limit), (calloutState->structReturnSize));
-		}
-		retOop = popRemappableOop();
-		storePointerofObjectwithValue(0, retOop, oop);
-		return methodReturnValue(retOop);
+		oop = ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSignedLongLong) >> 1)
+			? (atomicType & 1
+					? signed64BitIntegerFor(intRet)
+					: positive64BitIntegerFor(intRet))
+			: characterObjectOf(intRet & (
+#if SPURVM
+	0xFFFFFFFFUL
+#else /* SPURVM */
+	0xFF
+#endif /* SPURVM */
+	)));
+	l1:	/* end ffiCreateIntegralResultOop:ofAtomicType:in: */;
 	}
-	if ((atomicType == FFITypeSingleFloat)
-	 || (atomicType == FFITypeDoubleFloat)) {
-		return methodReturnValue(floatObjectOf(floatRet));
-	}
-	return methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
+	return methodReturnValue(oop);
 }
 
 
@@ -1757,6 +1859,7 @@
     sqInt argTypes1;
     sqInt atomicType;
     sqInt atomicType1;
+    sqInt byteSize;
     CalloutState *calloutState;
     sqInt classOop;
     sqInt cPointer;
@@ -1769,10 +1872,13 @@
     sqInt i;
     sqInt i1;
     usqLong intRet;
+    extern void loadFloatRegs(double, double, double, double, double, double, double, double);
+    sqInt mask;
     sqInt myThreadIndex;
     sqInt oop;
     sqInt oop1;
     sqInt oop2;
+    sqInt oop3;
     void *pointer;
     int *ptr;
     sqInt *ptr1;
@@ -1783,6 +1889,7 @@
     sqInt retOop;
     sqInt retOop1;
     sqInt retType;
+    sqInt shift;
     sqInt specLiteral;
     sqInt specLiteral1;
     sqInt stackSize;
@@ -1792,6 +1899,7 @@
     CalloutState theCalloutState;
     sqInt typeSpec;
     sqInt typeSpec1;
+    usqLong value;
 
 	floatRet = 0;
 	intRet = 0;
@@ -1977,6 +2085,7 @@
 		storeIntegerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, stackSize);
 	}
 	/* begin ffiCalloutTo:SpecOnStack:in: */
+	;
 	
 #  if COGMTVM
 	if (((calloutState->callFlags)) & FFICallFlagThreaded) {
@@ -1994,12 +2103,17 @@
 	/* begin atomicTypeOf: */
 	typeSpec = (calloutState->ffiRetHeader);
 	atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if (atomicType == FFITypeSingleFloat) {
-		floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		if (atomicType == FFITypeSingleFloat) {
+			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+		}
+		else {
+
+			/* atomicType = FFITypeDoubleFloat */
+
+			floatRet = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+		}
 	}
-	if (atomicType == FFITypeDoubleFloat) {
-		floatRet = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
-	}
 	else {
 		intRet = dispatchFunctionPointerwithwithwithwith(((usqLong (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 	}
@@ -2014,115 +2128,212 @@
 
 #  endif /* COGMTVM */
 
-	if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
-		/* begin ffiReturnPointer:ofType:in: */
-		/* begin ffiReturnType: */
-		specLiteral1 = (argArrayOrNil != null
-			? stackValue(1)
-			: literalofMethod(0, primitiveMethod()));
-		argTypes1 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
-		retType = fetchPointerofObject(0, argTypes1);
-		retClass1 = fetchPointerofObject(1, retType);
-		if (retClass1 == (nilObject())) {
+	if (((calloutState->ffiRetHeader)) & (FFIFlagPointer + FFIFlagStructure)) {
 
-			/* Create ExternalData upon return */
+		/* Note: Order is important here since FFIFlagPointer + FFIFlagStructure is used to represent
+		   'typedef void* VoidPointer' and VoidPointer must be returned as pointer *not* as struct. */
 
-			/* begin atomicTypeOf: */
-			typeSpec1 = (calloutState->ffiRetHeader);
-			atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-			if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+		if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
+			/* begin ffiReturnPointer:ofType:in: */
+			/* begin ffiReturnType: */
+			specLiteral1 = (argArrayOrNil != null
+				? stackValue(1)
+				: literalofMethod(0, primitiveMethod()));
+			argTypes1 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
+			retType = fetchPointerofObject(0, argTypes1);
+			retClass1 = fetchPointerofObject(1, retType);
+			if (retClass1 == (nilObject())) {
 
-				/* String return */
+				/* Create ExternalData upon return */
 
-				/* begin ffiReturnCStringFrom: */
-				cPointer = ((usqInt) intRet);
-				if (cPointer == null) {
-					result = methodReturnValue(nilObject());
-					goto l5;
+				/* begin atomicTypeOf: */
+				typeSpec1 = (calloutState->ffiRetHeader);
+				atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+				if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+
+					/* String return */
+
+					/* begin ffiReturnCStringFrom: */
+					cPointer = ((usqInt) intRet);
+					if (cPointer == null) {
+						methodReturnValue(nilObject());
+						goto l6;
+					}
+					cString = ((char *) cPointer);
+					strLen = 0;
+					while (!((cString[strLen]) == 0)) {
+						strLen += 1;
+					}
+					strOop = instantiateClassindexableSize(classString(), strLen);
+					strPtr = firstIndexableField(strOop);
+					for (i1 = 0; i1 < strLen; i1 += 1) {
+						strPtr[i1] = (cString[i1]);
+					}
+					methodReturnValue(strOop);
+					goto l6;
 				}
-				cString = ((char *) cPointer);
-				strLen = 0;
-				while (!((cString[strLen]) == 0)) {
-					strLen += 1;
-				}
-				strOop = instantiateClassindexableSize(classString(), strLen);
-				strPtr = firstIndexableField(strOop);
-				for (i1 = 0; i1 < strLen; i1 += 1) {
-					strPtr[i1] = (cString[i1]);
-				}
-				result = methodReturnValue(strOop);
-				goto l5;
+				
+#if SPURVM
+				oop2 = instantiateClassindexableSize(classExternalAddress(), 4);
+				ptr1 = firstIndexableField(oop2);
+				ptr1[0] = (((sqInt) intRet));
+				
+#if SPURVM
+				retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+
+#else /* SPURVM */
+				pushRemappableOop(oop2);
+				retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+				oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+				storePointerofObjectwithValue(0, retOop1, oop2);
+
+#else /* SPURVM */
+				pushRemappableOop(retType);
+				oop2 = instantiateClassindexableSize(classExternalAddress(), 4);
+				ptr1 = firstIndexableField(oop2);
+				ptr1[0] = (((sqInt) intRet));
+				
+#if SPURVM
+				retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+
+#else /* SPURVM */
+				pushRemappableOop(oop2);
+				retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+				oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+				storePointerofObjectwithValue(0, retOop1, oop2);
+				retType = popRemappableOop()
+#endif /* SPURVM */
+;
+				storePointerofObjectwithValue(1, retOop1, retType);
+				methodReturnValue(retOop1);
+				goto l6;
 			}
-			pushRemappableOop(retType);
-			oop1 = instantiateClassindexableSize(classExternalAddress(), 4);
-			ptr1 = firstIndexableField(oop1);
+			classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
+				? classByteArray()
+				: classExternalAddress());
+			
+#if SPURVM
+			oop2 = instantiateClassindexableSize(classOop, 4);
+
+#else /* SPURVM */
+			pushRemappableOop(retClass1);
+			oop2 = instantiateClassindexableSize(classOop, 4);
+			retClass1 = popRemappableOop()
+#endif /* SPURVM */
+;
+			ptr1 = firstIndexableField(oop2);
 			ptr1[0] = (((sqInt) intRet));
-			pushRemappableOop(oop1);
-			retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+			
+#if SPURVM
+			retOop1 = instantiateClassindexableSize(retClass1, 0);
 
-			/* external address */
+#else /* SPURVM */
+			pushRemappableOop(oop2);
+			retOop1 = instantiateClassindexableSize(retClass1, 0);
+			oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+			storePointerofObjectwithValue(0, retOop1, oop2);
+			result = methodReturnValue(retOop1);
+		l6:	/* end ffiReturnPointer:ofType:in: */;
+		}
+		else {
+			/* begin ffiReturnStruct:ofType:in: */
+			/* begin ffiReturnType: */
+			specLiteral = (argArrayOrNil != null
+				? stackValue(1)
+				: literalofMethod(0, primitiveMethod()));
+			argTypes = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
+			ffiRetType = fetchPointerofObject(0, argTypes);
+			retClass = fetchPointerofObject(1, ffiRetType);
+			retOop = instantiateClassindexableSize(retClass, 0);
+			
+#if SPURVM
+			oop1 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
 
-			oop1 = popRemappableOop();
-			storePointerofObjectwithValue(0, retOop1, oop1);
+#else /* SPURVM */
+			pushRemappableOop(retOop);
+			oop1 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
+			retOop = popRemappableOop()
+#endif /* SPURVM */
+;
+			if (returnStructInRegisters((calloutState->structReturnSize))) {
+				memcpy(firstIndexableField(oop1), (&intRet), (calloutState->structReturnSize));
+			}
+			else {
+				memcpy(firstIndexableField(oop1), (calloutState->limit), (calloutState->structReturnSize));
+			}
+			storePointerofObjectwithValue(0, retOop, oop1);
+			result = methodReturnValue(retOop);
+		}
+		goto l7;
+	}
+	if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+		oop3 = floatObjectOf(floatRet);
+	}
+	else {
+		/* begin ffiCreateIntegralResultOop:ofAtomicType:in: */
+		assert(atomicType < FFITypeSingleFloat);
+		if (atomicType == FFITypeBool) {
 
-			/* return type */
+			/* Make sure bool honors the byte size requested */
 
-			oop1 = popRemappableOop();
-			storePointerofObjectwithValue(1, retOop1, oop1);
-			result = methodReturnValue(retOop1);
+			byteSize = ((calloutState->ffiRetHeader)) & FFIStructSizeMask;
+			value = (byteSize == (sizeof(intRet))
+				? intRet
+				: intRet & ((1 << (byteSize * 8)) - 1));
+			oop3 = (value == 0
+				? falseObject()
+				: trueObject());
 			goto l5;
 		}
-		pushRemappableOop(retClass1);
-		classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
-			? classByteArray()
-			: classExternalAddress());
-		oop1 = instantiateClassindexableSize(classOop, 4);
-		ptr1 = firstIndexableField(oop1);
-		ptr1[0] = (((sqInt) intRet));
+		if (atomicType <= FFITypeSignedInt) {
 
-		/* return class */
+			/* these are all generall integer returns */
 
-		retClass1 = popRemappableOop();
-		pushRemappableOop(oop1);
-		retOop1 = instantiateClassindexableSize(retClass1, 0);
+			if (atomicType <= FFITypeSignedShort) {
 
-		/* external address */
+				/* byte/short. first extract partial word, then sign extend */
 
-		oop1 = popRemappableOop();
-		storePointerofObjectwithValue(0, retOop1, oop1);
-		result = methodReturnValue(retOop1);
-		goto l5;
-	}
-	if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
-		/* begin ffiReturnStruct:ofType:in: */
-		/* begin ffiReturnType: */
-		specLiteral = (argArrayOrNil != null
-			? stackValue(1)
-			: literalofMethod(0, primitiveMethod()));
-		argTypes = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
-		ffiRetType = fetchPointerofObject(0, argTypes);
-		retClass = fetchPointerofObject(1, ffiRetType);
-		retOop = instantiateClassindexableSize(retClass, 0);
-		pushRemappableOop(retOop);
-		oop2 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
-		if (returnStructInRegisters((calloutState->structReturnSize))) {
-			memcpy(firstIndexableField(oop2), (&intRet), (calloutState->structReturnSize));
+
+				/* # of significant bits */
+
+				shift = (((usqInt) atomicType) >> 1) * 8;
+				value = intRet & ((1 << shift) - 1);
+				if (atomicType & 1) {
+
+					/* make the guy signed */
+
+					mask = 1 << (shift - 1);
+					value = (value & (mask - 1)) - (value & mask);
+				}
+				oop3 = integerObjectOf(value);
+				goto l5;
+			}
+			oop3 = (atomicType & 1
+				? signed32BitIntegerFor(intRet)
+				: positive32BitIntegerFor(intRet));
+			goto l5;
 		}
-		else {
-			memcpy(firstIndexableField(oop2), (calloutState->limit), (calloutState->structReturnSize));
-		}
-		retOop = popRemappableOop();
-		storePointerofObjectwithValue(0, retOop, oop2);
-		result = methodReturnValue(retOop);
-		goto l5;
+		oop3 = ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSignedLongLong) >> 1)
+			? (atomicType & 1
+					? signed64BitIntegerFor(intRet)
+					: positive64BitIntegerFor(intRet))
+			: characterObjectOf(intRet & (
+#if SPURVM
+	0xFFFFFFFFUL
+#else /* SPURVM */
+	0xFF
+#endif /* SPURVM */
+	)));
+	l5:	/* end ffiCreateIntegralResultOop:ofAtomicType:in: */;
 	}
-	if ((atomicType == FFITypeSingleFloat)
-	 || (atomicType == FFITypeDoubleFloat)) {
-		result = methodReturnValue(floatObjectOf(floatRet));
-		goto l5;
-	}
-	result = methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
-l5:	/* end ffiCalloutTo:SpecOnStack:in: */;
+	result = methodReturnValue(oop3);
+l7:	/* end ffiCalloutTo:SpecOnStack:in: */;
 	/* begin cleanupCalloutState: */
 	while (((calloutState->stringArgIndex)) > 0) {
 		free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
@@ -2195,7 +2406,7 @@
 		/* Make sure bool honors the byte size requested */
 
 		byteSize = ((calloutState->ffiRetHeader)) & FFIStructSizeMask;
-		value = (byteSize == 4
+		value = (byteSize == (sizeof(retVal))
 			? retVal
 			: retVal & ((1 << (byteSize * 8)) - 1));
 		return (value == 0
@@ -3338,41 +3549,70 @@
 			}
 			return methodReturnValue(strOop);
 		}
-		pushRemappableOop(retType);
+		
+#if SPURVM
 		oop = instantiateClassindexableSize(classExternalAddress(), 4);
 		ptr = firstIndexableField(oop);
 		ptr[0] = (((sqInt) retVal));
+		
+#if SPURVM
+		retOop = instantiateClassindexableSize(classExternalData(), 0);
+
+#else /* SPURVM */
 		pushRemappableOop(oop);
 		retOop = instantiateClassindexableSize(classExternalData(), 0);
+		oop = popRemappableOop()
+#endif /* SPURVM */
+;
+		storePointerofObjectwithValue(0, retOop, oop);
 
-		/* external address */
+#else /* SPURVM */
+		pushRemappableOop(retType);
+		oop = instantiateClassindexableSize(classExternalAddress(), 4);
+		ptr = firstIndexableField(oop);
+		ptr[0] = (((sqInt) retVal));
+		
+#if SPURVM
+		retOop = instantiateClassindexableSize(classExternalData(), 0);
 
-		oop = popRemappableOop();
+#else /* SPURVM */
+		pushRemappableOop(oop);
+		retOop = instantiateClassindexableSize(classExternalData(), 0);
+		oop = popRemappableOop()
+#endif /* SPURVM */
+;
 		storePointerofObjectwithValue(0, retOop, oop);
-
-		/* return type */
-
-		oop = popRemappableOop();
-		storePointerofObjectwithValue(1, retOop, oop);
+		retType = popRemappableOop()
+#endif /* SPURVM */
+;
+		storePointerofObjectwithValue(1, retOop, retType);
 		return methodReturnValue(retOop);
 	}
-	pushRemappableOop(retClass);
 	classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
 		? classByteArray()
 		: classExternalAddress());
+	
+#if SPURVM
 	oop = instantiateClassindexableSize(classOop, 4);
+
+#else /* SPURVM */
+	pushRemappableOop(retClass);
+	oop = instantiateClassindexableSize(classOop, 4);
+	retClass = popRemappableOop()
+#endif /* SPURVM */
+;
 	ptr = firstIndexableField(oop);
 	ptr[0] = (((sqInt) retVal));
+	
+#if SPURVM
+	retOop = instantiateClassindexableSize(retClass, 0);
 
-	/* return class */
-
-	retClass = popRemappableOop();
+#else /* SPURVM */
 	pushRemappableOop(oop);
 	retOop = instantiateClassindexableSize(retClass, 0);
-
-	/* external address */
-
-	oop = popRemappableOop();
+	oop = popRemappableOop()
+#endif /* SPURVM */
+;
 	storePointerofObjectwithValue(0, retOop, oop);
 	return methodReturnValue(retOop);
 }
@@ -3392,15 +3632,22 @@
 
 	retClass = fetchPointerofObject(1, ffiRetType);
 	retOop = instantiateClassindexableSize(retClass, 0);
+	
+#if SPURVM
+	oop = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
+
+#else /* SPURVM */
 	pushRemappableOop(retOop);
 	oop = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
+	retOop = popRemappableOop()
+#endif /* SPURVM */
+;
 	if (returnStructInRegisters((calloutState->structReturnSize))) {
 		memcpy(firstIndexableField(oop), (&longLongRet), (calloutState->structReturnSize));
 	}
 	else {
 		memcpy(firstIndexableField(oop), (calloutState->limit), (calloutState->structReturnSize));
 	}
-	retOop = popRemappableOop();
 	storePointerofObjectwithValue(0, retOop, oop);
 	return methodReturnValue(retOop);
 }
@@ -3584,6 +3831,8 @@
     sqInt atomicType1;
     sqInt atomicType11;
     sqInt atomicType2;
+    sqInt byteSize;
+    sqInt byteSize1;
     CalloutState *calloutState;
     CalloutState *calloutState1;
     sqInt classOop;
@@ -3609,6 +3858,10 @@
     sqInt i3;
     usqLong intRet;
     usqLong intRet1;
+    extern void loadFloatRegs(double, double, double, double, double, double, double, double);
+    extern void loadFloatRegs1(double, double, double, double, double, double, double, double);
+    sqInt mask;
+    sqInt mask1;
     sqInt meth;
     sqInt myThreadIndex;
     sqInt myThreadIndex1;
@@ -3619,7 +3872,9 @@
     sqInt oop11;
     sqInt oop12;
     sqInt oop2;
+    sqInt oop21;
     sqInt oop3;
+    sqInt oop4;
     void *pointer;
     void *pointer1;
     int *ptr;
@@ -3642,6 +3897,8 @@
     sqInt retryCount;
     sqInt retType;
     sqInt retType1;
+    sqInt shift;
+    sqInt shift1;
     sqInt specLiteral;
     sqInt specLiteral1;
     sqInt specLiteral11;
@@ -3660,6 +3917,8 @@
     sqInt typeSpec1;
     sqInt typeSpec11;
     sqInt typeSpec2;
+    usqLong value;
+    usqLong value1;
 
 	floatRet = 0;
 	floatRet1 = 0;
@@ -3872,6 +4131,7 @@
 			storeIntegerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, stackSize);
 		}
 		/* begin ffiCalloutTo:SpecOnStack:in: */
+		;
 		
 #    if COGMTVM
 		if (((calloutState->callFlags)) & FFICallFlagThreaded) {
@@ -3889,12 +4149,17 @@
 		/* begin atomicTypeOf: */
 		typeSpec = (calloutState->ffiRetHeader);
 		atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-		if (atomicType == FFITypeSingleFloat) {
-			floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+			if (atomicType == FFITypeSingleFloat) {
+				floatRet = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+			}
+			else {
+
+				/* atomicType = FFITypeDoubleFloat */
+
+				floatRet = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
+			}
 		}
-		if (atomicType == FFITypeDoubleFloat) {
-			floatRet = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
-		}
 		else {
 			intRet = dispatchFunctionPointerwithwithwithwith(((usqLong (*)(int, int, int, int)) (((void *) address))), ((calloutState->integerRegisters))[0], ((calloutState->integerRegisters))[1], ((calloutState->integerRegisters))[2], ((calloutState->integerRegisters))[3]);
 		}
@@ -3909,115 +4174,212 @@
 
 #    endif /* COGMTVM */
 
-		if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
-			/* begin ffiReturnPointer:ofType:in: */
-			/* begin ffiReturnType: */
-			specLiteral1 = (null != null
-				? stackValue(1)
-				: literalofMethod(0, primitiveMethod()));
-			argTypes1 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
-			retType = fetchPointerofObject(0, argTypes1);
-			retClass1 = fetchPointerofObject(1, retType);
-			if (retClass1 == (nilObject())) {
+		if (((calloutState->ffiRetHeader)) & (FFIFlagPointer + FFIFlagStructure)) {
 
-				/* Create ExternalData upon return */
+			/* Note: Order is important here since FFIFlagPointer + FFIFlagStructure is used to represent
+			   'typedef void* VoidPointer' and VoidPointer must be returned as pointer *not* as struct. */
 
-				/* begin atomicTypeOf: */
-				typeSpec1 = (calloutState->ffiRetHeader);
-				atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-				if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+			if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
+				/* begin ffiReturnPointer:ofType:in: */
+				/* begin ffiReturnType: */
+				specLiteral1 = (null != null
+					? stackValue(1)
+					: literalofMethod(0, primitiveMethod()));
+				argTypes1 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
+				retType = fetchPointerofObject(0, argTypes1);
+				retClass1 = fetchPointerofObject(1, retType);
+				if (retClass1 == (nilObject())) {
 
-					/* String return */
+					/* Create ExternalData upon return */
 
-					/* begin ffiReturnCStringFrom: */
-					cPointer = ((usqInt) intRet);
-					if (cPointer == null) {
-						result1 = methodReturnValue(nilObject());
-						goto l11;
+					/* begin atomicTypeOf: */
+					typeSpec1 = (calloutState->ffiRetHeader);
+					atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+					if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+
+						/* String return */
+
+						/* begin ffiReturnCStringFrom: */
+						cPointer = ((usqInt) intRet);
+						if (cPointer == null) {
+							methodReturnValue(nilObject());
+							goto l12;
+						}
+						cString = ((char *) cPointer);
+						strLen = 0;
+						while (!((cString[strLen]) == 0)) {
+							strLen += 1;
+						}
+						strOop = instantiateClassindexableSize(classString(), strLen);
+						strPtr = firstIndexableField(strOop);
+						for (i2 = 0; i2 < strLen; i2 += 1) {
+							strPtr[i2] = (cString[i2]);
+						}
+						methodReturnValue(strOop);
+						goto l12;
 					}
-					cString = ((char *) cPointer);
-					strLen = 0;
-					while (!((cString[strLen]) == 0)) {
-						strLen += 1;
-					}
-					strOop = instantiateClassindexableSize(classString(), strLen);
-					strPtr = firstIndexableField(strOop);
-					for (i2 = 0; i2 < strLen; i2 += 1) {
-						strPtr[i2] = (cString[i2]);
-					}
-					result1 = methodReturnValue(strOop);
-					goto l11;
+					
+#if SPURVM
+					oop2 = instantiateClassindexableSize(classExternalAddress(), 4);
+					ptr2 = firstIndexableField(oop2);
+					ptr2[0] = (((sqInt) intRet));
+					
+#if SPURVM
+					retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+
+#else /* SPURVM */
+					pushRemappableOop(oop2);
+					retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+					oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+					storePointerofObjectwithValue(0, retOop1, oop2);
+
+#else /* SPURVM */
+					pushRemappableOop(retType);
+					oop2 = instantiateClassindexableSize(classExternalAddress(), 4);
+					ptr2 = firstIndexableField(oop2);
+					ptr2[0] = (((sqInt) intRet));
+					
+#if SPURVM
+					retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+
+#else /* SPURVM */
+					pushRemappableOop(oop2);
+					retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+					oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+					storePointerofObjectwithValue(0, retOop1, oop2);
+					retType = popRemappableOop()
+#endif /* SPURVM */
+;
+					storePointerofObjectwithValue(1, retOop1, retType);
+					methodReturnValue(retOop1);
+					goto l12;
 				}
-				pushRemappableOop(retType);
-				oop11 = instantiateClassindexableSize(classExternalAddress(), 4);
-				ptr2 = firstIndexableField(oop11);
+				classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
+					? classByteArray()
+					: classExternalAddress());
+				
+#if SPURVM
+				oop2 = instantiateClassindexableSize(classOop, 4);
+
+#else /* SPURVM */
+				pushRemappableOop(retClass1);
+				oop2 = instantiateClassindexableSize(classOop, 4);
+				retClass1 = popRemappableOop()
+#endif /* SPURVM */
+;
+				ptr2 = firstIndexableField(oop2);
 				ptr2[0] = (((sqInt) intRet));
-				pushRemappableOop(oop11);
-				retOop1 = instantiateClassindexableSize(classExternalData(), 0);
+				
+#if SPURVM
+				retOop1 = instantiateClassindexableSize(retClass1, 0);
 
-				/* external address */
+#else /* SPURVM */
+				pushRemappableOop(oop2);
+				retOop1 = instantiateClassindexableSize(retClass1, 0);
+				oop2 = popRemappableOop()
+#endif /* SPURVM */
+;
+				storePointerofObjectwithValue(0, retOop1, oop2);
+				result1 = methodReturnValue(retOop1);
+			l12:	/* end ffiReturnPointer:ofType:in: */;
+			}
+			else {
+				/* begin ffiReturnStruct:ofType:in: */
+				/* begin ffiReturnType: */
+				specLiteral = (null != null
+					? stackValue(1)
+					: literalofMethod(0, primitiveMethod()));
+				argTypes = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
+				ffiRetType = fetchPointerofObject(0, argTypes);
+				retClass = fetchPointerofObject(1, ffiRetType);
+				retOop = instantiateClassindexableSize(retClass, 0);
+				
+#if SPURVM
+				oop11 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
 
-				oop11 = popRemappableOop();
-				storePointerofObjectwithValue(0, retOop1, oop11);
+#else /* SPURVM */
+				pushRemappableOop(retOop);
+				oop11 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
+				retOop = popRemappableOop()
+#endif /* SPURVM */
+;
+				if (returnStructInRegisters((calloutState->structReturnSize))) {
+					memcpy(firstIndexableField(oop11), (&intRet), (calloutState->structReturnSize));
+				}
+				else {
+					memcpy(firstIndexableField(oop11), (calloutState->limit), (calloutState->structReturnSize));
+				}
+				storePointerofObjectwithValue(0, retOop, oop11);
+				result1 = methodReturnValue(retOop);
+			}
+			goto l13;
+		}
+		if ((((usqInt) atomicType) >> 1) == (FFITypeSingleFloat > 1)) {
+			oop3 = floatObjectOf(floatRet);
+		}
+		else {
+			/* begin ffiCreateIntegralResultOop:ofAtomicType:in: */
+			assert(atomicType < FFITypeSingleFloat);
+			if (atomicType == FFITypeBool) {
 
-				/* return type */
+				/* Make sure bool honors the byte size requested */
 
-				oop11 = popRemappableOop();
-				storePointerofObjectwithValue(1, retOop1, oop11);
-				result1 = methodReturnValue(retOop1);
+				byteSize = ((calloutState->ffiRetHeader)) & FFIStructSizeMask;
+				value = (byteSize == (sizeof(intRet))
+					? intRet
+					: intRet & ((1 << (byteSize * 8)) - 1));
+				oop3 = (value == 0
+					? falseObject()
+					: trueObject());
 				goto l11;
 			}
-			pushRemappableOop(retClass1);
-			classOop = (((calloutState->ffiRetHeader)) & FFIFlagStructure
-				? classByteArray()
-				: classExternalAddress());
-			oop11 = instantiateClassindexableSize(classOop, 4);
-			ptr2 = firstIndexableField(oop11);
-			ptr2[0] = (((sqInt) intRet));
+			if (atomicType <= FFITypeSignedInt) {
 
-			/* return class */
+				/* these are all generall integer returns */
 
-			retClass1 = popRemappableOop();
-			pushRemappableOop(oop11);
-			retOop1 = instantiateClassindexableSize(retClass1, 0);
+				if (atomicType <= FFITypeSignedShort) {
 
-			/* external address */
+					/* byte/short. first extract partial word, then sign extend */
 
-			oop11 = popRemappableOop();
-			storePointerofObjectwithValue(0, retOop1, oop11);
-			result1 = methodReturnValue(retOop1);
-			goto l11;
-		}
-		if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
-			/* begin ffiReturnStruct:ofType:in: */
-			/* begin ffiReturnType: */
-			specLiteral = (null != null
-				? stackValue(1)
-				: literalofMethod(0, primitiveMethod()));
-			argTypes = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
-			ffiRetType = fetchPointerofObject(0, argTypes);
-			retClass = fetchPointerofObject(1, ffiRetType);
-			retOop = instantiateClassindexableSize(retClass, 0);
-			pushRemappableOop(retOop);
-			oop2 = instantiateClassindexableSize(classByteArray(), (calloutState->structReturnSize));
-			if (returnStructInRegisters((calloutState->structReturnSize))) {
-				memcpy(firstIndexableField(oop2), (&intRet), (calloutState->structReturnSize));
+
+					/* # of significant bits */
+
+					shift = (((usqInt) atomicType) >> 1) * 8;
+					value = intRet & ((1 << shift) - 1);
+					if (atomicType & 1) {
+
+						/* make the guy signed */
+
+						mask = 1 << (shift - 1);
+						value = (value & (mask - 1)) - (value & mask);
+					}
+					oop3 = integerObjectOf(value);
+					goto l11;
+				}
+				oop3 = (atomicType & 1
+					? signed32BitIntegerFor(intRet)
+					: positive32BitIntegerFor(intRet));
+				goto l11;
 			}
-			else {
-				memcpy(firstIndexableField(oop2), (calloutState->limit), (calloutState->structReturnSize));
-			}
-			retOop = popRemappableOop();
-			storePointerofObjectwithValue(0, retOop, oop2);
-			result1 = methodReturnValue(retOop);
-			goto l11;
+			oop3 = ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSignedLongLong) >> 1)
+				? (atomicType & 1
+						? signed64BitIntegerFor(intRet)
+						: positive64BitIntegerFor(intRet))
+				: characterObjectOf(intRet & (
+#if SPURVM
+	0xFFFFFFFFUL
+#else /* SPURVM */
+	0xFF
+#endif /* SPURVM */
+	)));
+		l11:	/* end ffiCreateIntegralResultOop:ofAtomicType:in: */;
 		}
-		if ((atomicType == FFITypeSingleFloat)
-		 || (atomicType == FFITypeDoubleFloat)) {
-			result1 = methodReturnValue(floatObjectOf(floatRet));
-			goto l11;
-		}
-		result1 = methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
-	l11:	/* end ffiCalloutTo:SpecOnStack:in: */;
+		result1 = methodReturnValue(oop3);
+	l13:	/* end ffiCalloutTo:SpecOnStack:in: */;
 		/* begin cleanupCalloutState: */
 		while (((calloutState->stringArgIndex)) > 0) {
 			free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
@@ -4225,6 +4587,7 @@
 		storeIntegerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, stackSize1);
 	}
 	/* begin ffiCalloutTo:SpecOnStack:in: */
+	;
 	
 #  if COGMTVM
 	if (((calloutState1->callFlags)) & FFICallFlagThreaded) {
@@ -4242,12 +4605,17 @@
 	/* begin atomicTypeOf: */
 	typeSpec2 = (calloutState1->ffiRetHeader);
 	atomicType2 = ((usqInt) (typeSpec2 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-	if (atomicType2 == FFITypeSingleFloat) {
-		floatRet1 = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
+	if ((((usqInt) atomicType2) >> 1) == (FFITypeSingleFloat > 1)) {
+		if (atomicType2 == FFITypeSingleFloat) {
+			floatRet1 = dispatchFunctionPointerwithwithwithwith(((float (*)(int, int, int, int)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
+		}
+		else {
+
+			/* atomicType = FFITypeDoubleFloat */
+
+			floatRet1 = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
+		}
 	}
-	if (atomicType2 == FFITypeDoubleFloat) {
-		floatRet1 = dispatchFunctionPointerwithwithwithwith(((double (*)(int, int, int, int)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
-	}
 	else {
 		intRet1 = dispatchFunctionPointerwithwithwithwith(((usqLong (*)(int, int, int, int)) (((void *) address1))), ((calloutState1->integerRegisters))[0], ((calloutState1->integerRegisters))[1], ((calloutState1->integerRegisters))[2], ((calloutState1->integerRegisters))[3]);
 	}
@@ -4262,115 +4630,212 @@
 
 #  endif /* COGMTVM */
 
-	if (((calloutState1->ffiRetHeader)) & FFIFlagPointer) {
-		/* begin ffiReturnPointer:ofType:in: */
-		/* begin ffiReturnType: */
-		specLiteral11 = (null != null
-			? stackValue(1)
-			: literalofMethod(0, primitiveMethod()));
-		argTypes11 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral11);
-		retType1 = fetchPointerofObject(0, argTypes11);
-		retClass11 = fetchPointerofObject(1, retType1);
-		if (retClass11 == (nilObject())) {
+	if (((calloutState1->ffiRetHeader)) & (FFIFlagPointer + FFIFlagStructure)) {
 
-			/* Create ExternalData upon return */
+		/* Note: Order is important here since FFIFlagPointer + FFIFlagStructure is used to represent
+		   'typedef void* VoidPointer' and VoidPointer must be returned as pointer *not* as struct. */
 
-			/* begin atomicTypeOf: */
-			typeSpec11 = (calloutState1->ffiRetHeader);
-			atomicType11 = ((usqInt) (typeSpec11 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
-			if ((((usqInt) atomicType11) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+		if (((calloutState1->ffiRetHeader)) & FFIFlagPointer) {
+			/* begin ffiReturnPointer:ofType:in: */
+			/* begin ffiReturnType: */
+			specLiteral11 = (null != null
+				? stackValue(1)
+				: literalofMethod(0, primitiveMethod()));
+			argTypes11 = fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral11);
+			retType1 = fetchPointerofObject(0, argTypes11);
+			retClass11 = fetchPointerofObject(1, retType1);
+			if (retClass11 == (nilObject())) {
 
-				/* String return */
+				/* Create ExternalData upon return */
 
-				/* begin ffiReturnCStringFrom: */
-				cPointer1 = ((usqInt) intRet1);
-				if (cPointer1 == null) {
-					result2 = methodReturnValue(nilObject());
-					goto l12;
+				/* begin atomicTypeOf: */
+				typeSpec11 = (calloutState1->ffiRetHeader);

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list