[Vm-dev] VM Maker Inbox: VMMaker.oscog-nice.2679.mcz
commits at source.squeak.org
commits at source.squeak.org
Mon Jan 27 23:30:00 UTC 2020
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox:
http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2679.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2679
Author: nice
Time: 28 January 2020, 12:29:02.819279 am
UUID: 7b4b7f36-4bf2-4911-88ea-df99e8bb3ccb
Ancestors: VMMaker.oscog-nice.2678
Fixup incorrect count of double registers required to ffiPushStructure:
=============== Diff against VMMaker.oscog-nice.2678 ===============
Item was changed:
----- Method: ThreadedX64SysVFFIPlugin>>ffiPushStructure:ofSize:typeSpec:ofLength:in: (in category 'marshalling') -----
ffiPushStructure: pointer ofSize: structSize typeSpec: argSpec ofLength: argSpecSize in: calloutState
<var: #pointer type: #'void *'>
<var: #argSpec type: #'sqInt *'>
<var: #calloutState type: #'CalloutState *'>
<inline: true>
| roundedSize registerType numDoubleRegisters numIntegerRegisters passField0InXmmReg passField1InXmmReg |
structSize <= 16 ifTrue:
["See sec 3.2.3 of http://people.freebsd.org/~obrien/amd64-elf-abi.pdf. (dravft version 0.90).
All of the folowing are passed in registers:
typedef struct { long a; } s0;
typedef struct { double a; } s1;
typedef struct { long a; double b; } s2;
typedef struct { int a; int b; double c; } s2a;
typedef struct { short a; short b; short c; short d; double e; } s2b;
typedef struct { long a; float b; } s2f;
typedef struct { long a; float b; float c; } s2g;
typedef struct { int a; float b; int c; float d; } s2h;"
registerType := self registerTypeForStructSpecs: (self cCoerce: argSpec to: #'unsigned int *') OfLength: argSpecSize.
passField0InXmmReg := (registerType bitAnd: 1) = 0.
structSize <= 8
ifTrue:
[numIntegerRegisters := registerType bitAnd: 1.
numDoubleRegisters := 1 - numIntegerRegisters]
ifFalse:
[passField1InXmmReg := (registerType bitAnd: 2) = 0.
+ numIntegerRegisters := (registerType bitAnd: 2) >> 1 + (registerType bitAnd: 1).
+ numDoubleRegisters := 2 - numIntegerRegisters].
- numIntegerRegisters := (registerType bitAnd: 2) >> 1 + (registerType bitAnd: 1).
- numDoubleRegisters := 1 - numIntegerRegisters].
(calloutState floatRegisterIndex + numDoubleRegisters <= NumFloatRegArgs
and: [calloutState integerRegisterIndex + numIntegerRegisters <= NumIntRegArgs]) ifTrue:
[passField0InXmmReg
ifTrue: [self ffiPushDoubleFloat: ((self cCoerceSimple: pointer to: #'double *') at: 0) in: calloutState]
ifFalse: [self ffiPushSignedLongLong: ((self cCoerceSimple: pointer to: #'long long *') at: 0) in: calloutState].
structSize > 8 ifTrue:
[passField1InXmmReg
ifTrue: [self ffiPushDoubleFloat: ((self cCoerceSimple: pointer to: #'double *') at: 1) in: calloutState]
ifFalse: [self ffiPushSignedLongLong: ((self cCoerceSimple: pointer to: #'long long *') at: 1) in: calloutState]].
^0]].
roundedSize := structSize + 7 bitClear: 7.
calloutState currentArg + roundedSize > calloutState limit ifTrue:
[^FFIErrorCallFrameTooBig].
self memcpy: calloutState currentArg _: (self cCoerceSimple: pointer to: 'char *') _: structSize.
calloutState currentArg: calloutState currentArg + roundedSize.
^0!
More information about the Vm-dev
mailing list