Skip to content

Commit 4b43545

Browse files
committed
CogVM source as per VMMaker.oscog-eem.3545
On ARM64 if homogenous float aggregates can be passed in registers then their fields are spread across the least-significant halves of the outgoing double- precision float argument registers. Thanks to Leonard Geier and Tom Beckmann for this fix. BTW, generating the RiscV64FFIPlugin also as this is written as a subclass of ThreadedARM64FFIPlugin. This may or may not be correct. Ken Dickey can you check? P.S. we need the FFI test suite extended with tests for homogenous float aggregates.
1 parent e93bc0e commit 4b43545

3 files changed

Lines changed: 120 additions & 42 deletions

File tree

src/plugins/SqueakFFIPrims/ARM64AppleFFIPlugin.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* Automatically generated by
2-
VMPluginCodeGenerator VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca
3-
(Compiler-eem.512)
2+
VMPluginCodeGenerator VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34
3+
(Compiler-eem.514)
44
from
5-
ThreadedARM64AppleFFIPlugin VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca
5+
ThreadedARM64AppleFFIPlugin VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34
66
*/
7-
static char __buildInfo[] = "ThreadedARM64AppleFFIPlugin VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca " __DATE__ ;
7+
static char __buildInfo[] = "ThreadedARM64AppleFFIPlugin VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34 " __DATE__ ;
88

99

1010
#include "config.h"
@@ -178,7 +178,7 @@ static char __buildInfo[] = "ThreadedARM64AppleFFIPlugin VMMaker.oscog-eem.3478
178178
#define MaxNumArgs 15
179179
#define NumFloatRegArgs 8
180180
#define NumIntRegArgs 8
181-
#define PluginVersionInfo " VMMaker.oscog-eem.3478"
181+
#define PluginVersionInfo " VMMaker.oscog-eem.3545"
182182

183183
typedef struct {
184184
char *argVector;
@@ -547,7 +547,7 @@ extern sqInt trueObject(void);
547547
extern
548548
#endif
549549
struct VirtualMachine* interpreterProxy;
550-
static const char *moduleName = "ARM64AppleFFIPlugin VMMaker.oscog-eem.3478 " INT_EXT;
550+
static const char *moduleName = "ARM64AppleFFIPlugin VMMaker.oscog-eem.3545 " INT_EXT;
551551
static sqInt nilObj;
552552

553553

@@ -627,6 +627,7 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
627627
char *copy;
628628
sqInt err;
629629
double floatValue;
630+
sqInt i;
630631
usqLong intValue;
631632
sqInt isAlienObj;
632633
int isExternalAddress;
@@ -743,10 +744,23 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
743744
if (structIsHomogenousFloatArrayOfSizetypeSpecofLength(structSize, argSpec1, argSpecSize)) {
744745
availableRegisterSpace = (NumFloatRegArgs - ((calloutState->floatRegisterIndex))) * BytesPerWord;
745746
if (structSize <= availableRegisterSpace) {
746-
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
747+
if ((((usqInt)(((argSpec1[1]) & FFIAtomicTypeMask))) >> FFIAtomicTypeShift) == FFITypeDoubleFloat) {
748+
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
747749

748-
/* Round structSize up and divide by 8 ( NB: _not_ 4 !) */
749-
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
750+
/* Round structSize up and divide by 8 (NB: _not_ 4 !) */
751+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
752+
}
753+
else {
754+
for (i = 0; i < (structSize / (sizeof(float))); i += 1) {
755+
(*((float*) ((&(((calloutState->floatRegisters))[((calloutState->floatRegisterIndex)) + i])))) = (((float *) ptrAddress))[i]);
756+
}
757+
758+
/* Round structSize up and divide by 4 (NB: _not_ 8 !) */
759+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 3))) >> 2)));
760+
}
761+
762+
/* doubles can be copied in one go
763+
floats are passed in the single-precision half of the double register values and so must be copied piece-by-piece */
750764
return 0;
751765
}
752766

@@ -838,10 +852,23 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
838852
if (structIsHomogenousFloatArrayOfSizetypeSpecofLength(structSize, argSpec1, argSpecSize)) {
839853
availableRegisterSpace = (NumFloatRegArgs - ((calloutState->floatRegisterIndex))) * BytesPerWord;
840854
if (structSize <= availableRegisterSpace) {
841-
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
855+
if ((((usqInt)(((argSpec1[1]) & FFIAtomicTypeMask))) >> FFIAtomicTypeShift) == FFITypeDoubleFloat) {
856+
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
842857

843-
/* Round structSize up and divide by 8 ( NB: _not_ 4 !) */
844-
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
858+
/* Round structSize up and divide by 8 (NB: _not_ 4 !) */
859+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
860+
}
861+
else {
862+
for (i = 0; i < (structSize / (sizeof(float))); i += 1) {
863+
(*((float*) ((&(((calloutState->floatRegisters))[((calloutState->floatRegisterIndex)) + i])))) = (((float *) ptrAddress))[i]);
864+
}
865+
866+
/* Round structSize up and divide by 4 (NB: _not_ 8 !) */
867+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 3))) >> 2)));
868+
}
869+
870+
/* doubles can be copied in one go
871+
floats are passed in the single-precision half of the double register values and so must be copied piece-by-piece */
845872
return 0;
846873
}
847874

@@ -4578,8 +4605,7 @@ structIsHomogenousFloatArrayOfSizetypeSpecofLength(sqInt structSize, unsigned in
45784605
unsigned int typeOfFirstField;
45794606
sqInt typeSpec;
45804607

4581-
if (!((structSize <= (4 * (sizeof(double))))
4582-
&& (argSpecSize <= 5))) {
4608+
if (!(argSpecSize <= 5)) {
45834609
return 0;
45844610
}
45854611

src/plugins/SqueakFFIPrims/ARM64FFIPlugin.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* Automatically generated by
2-
VMPluginCodeGenerator VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca
3-
(Compiler-eem.512)
2+
VMPluginCodeGenerator VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34
3+
(Compiler-eem.514)
44
from
5-
ThreadedARM64FFIPlugin VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca
5+
ThreadedARM64FFIPlugin VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34
66
*/
7-
static char __buildInfo[] = "ThreadedARM64FFIPlugin VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca " __DATE__ ;
7+
static char __buildInfo[] = "ThreadedARM64FFIPlugin VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34 " __DATE__ ;
88

99

1010
#include "config.h"
@@ -178,7 +178,7 @@ static char __buildInfo[] = "ThreadedARM64FFIPlugin VMMaker.oscog-eem.3478 uuid:
178178
#define MaxNumArgs 15
179179
#define NumFloatRegArgs 8
180180
#define NumIntRegArgs 8
181-
#define PluginVersionInfo " VMMaker.oscog-eem.3478"
181+
#define PluginVersionInfo " VMMaker.oscog-eem.3545"
182182

183183
typedef struct {
184184
char *argVector;
@@ -547,7 +547,7 @@ extern sqInt trueObject(void);
547547
extern
548548
#endif
549549
struct VirtualMachine* interpreterProxy;
550-
static const char *moduleName = "ARM64FFIPlugin VMMaker.oscog-eem.3478 " INT_EXT;
550+
static const char *moduleName = "ARM64FFIPlugin VMMaker.oscog-eem.3545 " INT_EXT;
551551
static sqInt nilObj;
552552

553553

@@ -627,6 +627,7 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
627627
char *copy;
628628
sqInt err;
629629
double floatValue;
630+
sqInt i;
630631
usqLong intValue;
631632
sqInt isAlienObj;
632633
int isExternalAddress;
@@ -743,10 +744,23 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
743744
if (structIsHomogenousFloatArrayOfSizetypeSpecofLength(structSize, argSpec1, argSpecSize)) {
744745
availableRegisterSpace = (NumFloatRegArgs - ((calloutState->floatRegisterIndex))) * BytesPerWord;
745746
if (structSize <= availableRegisterSpace) {
746-
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
747+
if ((((usqInt)(((argSpec1[1]) & FFIAtomicTypeMask))) >> FFIAtomicTypeShift) == FFITypeDoubleFloat) {
748+
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
747749

748-
/* Round structSize up and divide by 8 ( NB: _not_ 4 !) */
749-
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
750+
/* Round structSize up and divide by 8 (NB: _not_ 4 !) */
751+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
752+
}
753+
else {
754+
for (i = 0; i < (structSize / (sizeof(float))); i += 1) {
755+
(*((float*) ((&(((calloutState->floatRegisters))[((calloutState->floatRegisterIndex)) + i])))) = (((float *) ptrAddress))[i]);
756+
}
757+
758+
/* Round structSize up and divide by 4 (NB: _not_ 8 !) */
759+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 3))) >> 2)));
760+
}
761+
762+
/* doubles can be copied in one go
763+
floats are passed in the single-precision half of the double register values and so must be copied piece-by-piece */
750764
return 0;
751765
}
752766

@@ -831,10 +845,23 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
831845
if (structIsHomogenousFloatArrayOfSizetypeSpecofLength(structSize, argSpec1, argSpecSize)) {
832846
availableRegisterSpace = (NumFloatRegArgs - ((calloutState->floatRegisterIndex))) * BytesPerWord;
833847
if (structSize <= availableRegisterSpace) {
834-
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
848+
if ((((usqInt)(((argSpec1[1]) & FFIAtomicTypeMask))) >> FFIAtomicTypeShift) == FFITypeDoubleFloat) {
849+
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
835850

836-
/* Round structSize up and divide by 8 ( NB: _not_ 4 !) */
837-
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
851+
/* Round structSize up and divide by 8 (NB: _not_ 4 !) */
852+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
853+
}
854+
else {
855+
for (i = 0; i < (structSize / (sizeof(float))); i += 1) {
856+
(*((float*) ((&(((calloutState->floatRegisters))[((calloutState->floatRegisterIndex)) + i])))) = (((float *) ptrAddress))[i]);
857+
}
858+
859+
/* Round structSize up and divide by 4 (NB: _not_ 8 !) */
860+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 3))) >> 2)));
861+
}
862+
863+
/* doubles can be copied in one go
864+
floats are passed in the single-precision half of the double register values and so must be copied piece-by-piece */
838865
return 0;
839866
}
840867

@@ -4409,8 +4436,7 @@ structIsHomogenousFloatArrayOfSizetypeSpecofLength(sqInt structSize, unsigned in
44094436
unsigned int typeOfFirstField;
44104437
sqInt typeSpec;
44114438

4412-
if (!((structSize <= (4 * (sizeof(double))))
4413-
&& (argSpecSize <= 5))) {
4439+
if (!(argSpecSize <= 5)) {
44144440
return 0;
44154441
}
44164442

src/plugins/SqueakFFIPrims/RiscV64FFIPlugin.c

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/* Automatically generated by
2-
VMPluginCodeGenerator VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca
3-
(Compiler-eem.512)
2+
VMPluginCodeGenerator VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34
3+
(Compiler-eem.514)
44
from
5-
ThreadedRiscV64FFIPlugin VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca
5+
ThreadedRiscV64FFIPlugin VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34
66
*/
7-
static char __buildInfo[] = "ThreadedRiscV64FFIPlugin VMMaker.oscog-eem.3478 uuid: b32ccdc8-fc59-4e5c-b64a-901f820e72ca " __DATE__ ;
7+
static char __buildInfo[] = "ThreadedRiscV64FFIPlugin VMMaker.oscog-eem.3545 uuid: 94bd3515-6be5-45a4-a50b-5b012dae3a34 " __DATE__ ;
88

99

1010
#include "config.h"
@@ -178,7 +178,7 @@ static char __buildInfo[] = "ThreadedRiscV64FFIPlugin VMMaker.oscog-eem.3478 uui
178178
#define MaxNumArgs 15
179179
#define NumFloatRegArgs 8
180180
#define NumIntRegArgs 8
181-
#define PluginVersionInfo " VMMaker.oscog-eem.3478"
181+
#define PluginVersionInfo " VMMaker.oscog-eem.3545"
182182

183183
typedef struct {
184184
char *argVector;
@@ -546,7 +546,7 @@ extern sqInt trueObject(void);
546546
extern
547547
#endif
548548
struct VirtualMachine* interpreterProxy;
549-
static const char *moduleName = "RiscV64FFIPlugin VMMaker.oscog-eem.3478 " INT_EXT;
549+
static const char *moduleName = "RiscV64FFIPlugin VMMaker.oscog-eem.3545 " INT_EXT;
550550
static sqInt nilObj;
551551

552552

@@ -626,6 +626,7 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
626626
char *copy;
627627
sqInt err;
628628
double floatValue;
629+
sqInt i;
629630
usqLong intValue;
630631
sqInt isAlienObj;
631632
int isExternalAddress;
@@ -742,10 +743,23 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
742743
if (structIsHomogenousFloatArrayOfSizetypeSpecofLength(structSize, argSpec1, argSpecSize)) {
743744
availableRegisterSpace = (NumFloatRegArgs - ((calloutState->floatRegisterIndex))) * BytesPerWord;
744745
if (structSize <= availableRegisterSpace) {
745-
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
746+
if ((((usqInt)(((argSpec1[1]) & FFIAtomicTypeMask))) >> FFIAtomicTypeShift) == FFITypeDoubleFloat) {
747+
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
746748

747-
/* Round structSize up and divide by 8 ( NB: _not_ 4 !) */
748-
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
749+
/* Round structSize up and divide by 8 (NB: _not_ 4 !) */
750+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
751+
}
752+
else {
753+
for (i = 0; i < (structSize / (sizeof(float))); i += 1) {
754+
(*((float*) ((&(((calloutState->floatRegisters))[((calloutState->floatRegisterIndex)) + i])))) = (((float *) ptrAddress))[i]);
755+
}
756+
757+
/* Round structSize up and divide by 4 (NB: _not_ 8 !) */
758+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 3))) >> 2)));
759+
}
760+
761+
/* doubles can be copied in one go
762+
floats are passed in the single-precision half of the double register values and so must be copied piece-by-piece */
749763
return 0;
750764
}
751765

@@ -830,10 +844,23 @@ ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *c
830844
if (structIsHomogenousFloatArrayOfSizetypeSpecofLength(structSize, argSpec1, argSpecSize)) {
831845
availableRegisterSpace = (NumFloatRegArgs - ((calloutState->floatRegisterIndex))) * BytesPerWord;
832846
if (structSize <= availableRegisterSpace) {
833-
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
847+
if ((((usqInt)(((argSpec1[1]) & FFIAtomicTypeMask))) >> FFIAtomicTypeShift) == FFITypeDoubleFloat) {
848+
memcpy(((void *) ((&(((calloutState->floatRegisters))[(calloutState->floatRegisterIndex)])))), ptrAddress, structSize);
834849

835-
/* Round structSize up and divide by 8 ( NB: _not_ 4 !) */
836-
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
850+
/* Round structSize up and divide by 8 (NB: _not_ 4 !) */
851+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 7))) >> 3)));
852+
}
853+
else {
854+
for (i = 0; i < (structSize / (sizeof(float))); i += 1) {
855+
(*((float*) ((&(((calloutState->floatRegisters))[((calloutState->floatRegisterIndex)) + i])))) = (((float *) ptrAddress))[i]);
856+
}
857+
858+
/* Round structSize up and divide by 4 (NB: _not_ 8 !) */
859+
(calloutState->floatRegisterIndex = ((calloutState->floatRegisterIndex)) + ((((usqInt)((structSize + 3))) >> 2)));
860+
}
861+
862+
/* doubles can be copied in one go
863+
floats are passed in the single-precision half of the double register values and so must be copied piece-by-piece */
837864
return 0;
838865
}
839866

@@ -4445,8 +4472,7 @@ structIsHomogenousFloatArrayOfSizetypeSpecofLength(sqInt structSize, unsigned in
44454472
unsigned int typeOfFirstField;
44464473
sqInt typeSpec;
44474474

4448-
if (!((structSize <= (4 * (sizeof(double))))
4449-
&& (argSpecSize <= 5))) {
4475+
if (!(argSpecSize <= 5)) {
44504476
return 0;
44514477
}
44524478

0 commit comments

Comments
 (0)