Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox: http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2547.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2547 Author: nice Time: 31 August 2019, 2:02:51.22464 am UUID: 66e4c466-c54c-4035-a7fa-6078386cbc66 Ancestors: VMMaker.oscog-nice.2546
Fix genPrimitiveHighBit
We must not modify ReceiverResultReg when we CompletePrimitive (in case of negative receiver).
Hence, like in WIN64, we must better use TempReg.
=============== Diff against VMMaker.oscog-nice.2546 ===============
Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category 'primitive generators') ----- genPrimitiveHighBit + "Implementation notes: there are two reasons to use TempReg + -1) if primitive fails, ReceiverResultReg must remain unchanged (we CompletePrimitive) + -2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel X64. But Win64 uses R9 + Normally, this should be backEnd dependent, but for now we have a single 64bits target..." + | jumpNegativeReceiver | <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> "remove excess tag bits from the receiver oop" + cogit MoveR: ReceiverResultReg R: TempReg. self numSmallIntegerTagBits > 1 ifTrue: + [cogit OrCq: 1 << self numSmallIntegerTagBits - 1 R: TempReg. + cogit ArithmeticShiftRightCq: self numSmallIntegerTagBits - 1 R: TempReg]. - [cogit OrCq: 1 << self numSmallIntegerTagBits - 1 R: ReceiverResultReg. - cogit ArithmeticShiftRightCq: self numSmallIntegerTagBits - 1 R: ReceiverResultReg]. "and use the abstract cogit facility for case of single tag-bit" + jumpNegativeReceiver := cogit genHighBitIn: TempReg ofSmallIntegerOopWithSingleTagBit: TempReg. - jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. "Jump is NULL if above operation is not implemented, else return the result" jumpNegativeReceiver = 0 ifFalse: + [cogit MoveR: TempReg R: ReceiverResultReg. + cogit genConvertIntegerToSmallIntegerInReg: ReceiverResultReg. - [cogit genConvertIntegerToSmallIntegerInReg: ReceiverResultReg. cogit genPrimReturn. jumpNegativeReceiver jmpTarget: cogit Label]. ^CompletePrimitive!
Item was removed: - ----- Method: CogObjectRepresentation>>genPrimitiveHighBitgenPrimitiveHighBit (in category 'primitive generators') ----- - genPrimitiveHighBitgenPrimitiveHighBit - | jumpNegativeReceiver | - <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> - "remove excess tag bits from the receiver oop" - self numSmallIntegerTagBits > 1 - ifTrue: - [cogit OrCw: 1 << self numSmallIntegerTagBits - 1 R: ReceiverResultReg. - cogit ArithmeticShiftRightCq: self numSmallIntegerTagBits - 1 R: ReceiverResultReg]. - "and use the abstract cogit facility for case of single tag-bit" - jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. - "The jump instruction is NULL when backend does not really has a jitted implementation: fallback to normal primitive" - jumpNegativeReceiver = 0 ifTrue: [^CompletePrimitive]. - cogit genPrimReturn. - jumpNegativeReceiver jmpTarget: cogit Label. - ^UnimplementedPrimitive!
Item was removed: - ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveHighBit (in category 'primitive generators') ----- - genPrimitiveHighBit - "Implementation notes: same as super, but CLZ/BSR only work on 64bits for registers R0-R7 on Intel X64. - Normally, this should be backEnd dependent, but for now we have a single 64bits target..." - | jumpNegativeReceiver reg | - <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> - "remove excess tag bits from the receiver oop" - - ReceiverResultReg > 7 - ifTrue: [cogit MoveR: ReceiverResultReg R: (reg := TempReg)] - ifFalse: [reg := ReceiverResultReg]. - self numSmallIntegerTagBits > 1 - ifTrue: - [cogit OrCw: 1 << self numSmallIntegerTagBits - 1 R: reg. - cogit ArithmeticShiftRightCq: self numSmallIntegerTagBits - 1 R: reg]. - "and use the abstract cogit facility for case of single tag-bit" - jumpNegativeReceiver := cogit genHighBitIn: reg ofSmallIntegerOopWithSingleTagBit: reg. - "Jump is NULL if above operation is not implemented, else return the result" - jumpNegativeReceiver = 0 - ifFalse: - [ReceiverResultReg > 7 - ifTrue: [cogit MoveR: reg R: ReceiverResultReg]. - cogit genConvertIntegerToSmallIntegerInReg: ReceiverResultReg. - cogit genPrimReturn. - jumpNegativeReceiver jmpTarget: cogit Label]. - ^CompletePrimitive!
Hi Nicolas,
this looks great! Thanks for your patience while I've reviewed this. I do see that to implement CoInterpreter>>setPrimitiveDoMixedArithmetic: correctly we'll either have to discard JITed methods with primitives and remap context pcs. See e.g. CoInterpreterPrimitives>>primitiveVoidVMStateForMethod. I am happy to do this; the code needs a few changes anyway to make sure things still simulate. But you may be doing this anyway. If we step on each other's fingers then no worries. You can always commit your code over mine.
On Fri, Aug 30, 2019 at 5:04 PM commits@source.squeak.org wrote:
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox: http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2547.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2547 Author: nice Time: 31 August 2019, 2:02:51.22464 am UUID: 66e4c466-c54c-4035-a7fa-6078386cbc66 Ancestors: VMMaker.oscog-nice.2546
Fix genPrimitiveHighBit
We must not modify ReceiverResultReg when we CompletePrimitive (in case of negative receiver).
Hence, like in WIN64, we must better use TempReg.
=============== Diff against VMMaker.oscog-nice.2546 ===============
Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category 'primitive generators') ----- genPrimitiveHighBit
"Implementation notes: there are two reasons to use TempReg
-1) if primitive fails, ReceiverResultReg must remain unchanged
(we CompletePrimitive)
-2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel X64.
But Win64 uses R9
Normally, this should be backEnd dependent, but for now we have a
single 64bits target..."
| jumpNegativeReceiver | <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> "remove excess tag bits from the receiver oop"
cogit MoveR: ReceiverResultReg R: TempReg. self numSmallIntegerTagBits > 1 ifTrue:
[cogit OrCq: 1 << self numSmallIntegerTagBits - 1
R: TempReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: TempReg].
[cogit OrCq: 1 << self numSmallIntegerTagBits - 1
R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg]. "and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: TempReg
ofSmallIntegerOopWithSingleTagBit: TempReg.
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. "Jump is NULL if above operation is not implemented, else return the result" jumpNegativeReceiver = 0 ifFalse:
[cogit MoveR: TempReg R: ReceiverResultReg.
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
[cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg. cogit genPrimReturn. jumpNegativeReceiver jmpTarget: cogit Label]. ^CompletePrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentation>>genPrimitiveHighBitgenPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBitgenPrimitiveHighBit
| jumpNegativeReceiver |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits - 1
R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg.
"The jump instruction is NULL when backend does not really has a
jitted implementation: fallback to normal primitive"
jumpNegativeReceiver = 0 ifTrue: [^CompletePrimitive].
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label.
^UnimplementedPrimitive!
Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveHighBit
(in category 'primitive generators') -----
- genPrimitiveHighBit
"Implementation notes: same as super, but CLZ/BSR only work on
64bits for registers R0-R7 on Intel X64.
Normally, this should be backEnd dependent, but for now we have a
single 64bits target..."
| jumpNegativeReceiver reg |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
ReceiverResultReg > 7
ifTrue: [cogit MoveR: ReceiverResultReg R: (reg :=
TempReg)]
ifFalse: [reg := ReceiverResultReg].
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits - 1
R: reg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: reg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: reg
ofSmallIntegerOopWithSingleTagBit: reg.
"Jump is NULL if above operation is not implemented, else return
the result"
jumpNegativeReceiver = 0
ifFalse:
[ReceiverResultReg > 7
ifTrue: [cogit MoveR: reg R:
ReceiverResultReg].
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label].
^CompletePrimitive!
Hi Eliot, thanks. Yes, for now I let responsibility to image side (Smalltalk voidCogVMState), because it sounded complex to relink to interpreter... French say (but this might come from Sweden): do*n'**t cut** off **the** branch **you'**re **sitting** on*
Le mer. 4 sept. 2019 à 21:28, Eliot Miranda eliot.miranda@gmail.com a écrit :
Hi Nicolas,
this looks great! Thanks for your patience while I've reviewed this.
I do see that to implement CoInterpreter>>setPrimitiveDoMixedArithmetic: correctly we'll either have to discard JITed methods with primitives and remap context pcs. See e.g. CoInterpreterPrimitives>>primitiveVoidVMStateForMethod. I am happy to do this; the code needs a few changes anyway to make sure things still simulate. But you may be doing this anyway. If we step on each other's fingers then no worries. You can always commit your code over mine.
On Fri, Aug 30, 2019 at 5:04 PM commits@source.squeak.org wrote:
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox: http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2547.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2547 Author: nice Time: 31 August 2019, 2:02:51.22464 am UUID: 66e4c466-c54c-4035-a7fa-6078386cbc66 Ancestors: VMMaker.oscog-nice.2546
Fix genPrimitiveHighBit
We must not modify ReceiverResultReg when we CompletePrimitive (in case of negative receiver).
Hence, like in WIN64, we must better use TempReg.
=============== Diff against VMMaker.oscog-nice.2546 ===============
Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category 'primitive generators') ----- genPrimitiveHighBit
"Implementation notes: there are two reasons to use TempReg
-1) if primitive fails, ReceiverResultReg must remain unchanged
(we CompletePrimitive)
-2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel X64.
But Win64 uses R9
Normally, this should be backEnd dependent, but for now we have a
single 64bits target..."
| jumpNegativeReceiver | <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> "remove excess tag bits from the receiver oop"
cogit MoveR: ReceiverResultReg R: TempReg. self numSmallIntegerTagBits > 1 ifTrue:
[cogit OrCq: 1 << self numSmallIntegerTagBits - 1
R: TempReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: TempReg].
[cogit OrCq: 1 << self numSmallIntegerTagBits - 1
R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg]. "and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: TempReg
ofSmallIntegerOopWithSingleTagBit: TempReg.
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. "Jump is NULL if above operation is not implemented, else return the result" jumpNegativeReceiver = 0 ifFalse:
[cogit MoveR: TempReg R: ReceiverResultReg.
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
[cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg. cogit genPrimReturn. jumpNegativeReceiver jmpTarget: cogit Label]. ^CompletePrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentation>>genPrimitiveHighBitgenPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBitgenPrimitiveHighBit
| jumpNegativeReceiver |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits - 1
R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg.
"The jump instruction is NULL when backend does not really has a
jitted implementation: fallback to normal primitive"
jumpNegativeReceiver = 0 ifTrue: [^CompletePrimitive].
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label.
^UnimplementedPrimitive!
Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveHighBit
(in category 'primitive generators') -----
- genPrimitiveHighBit
"Implementation notes: same as super, but CLZ/BSR only work on
64bits for registers R0-R7 on Intel X64.
Normally, this should be backEnd dependent, but for now we have a
single 64bits target..."
| jumpNegativeReceiver reg |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
ReceiverResultReg > 7
ifTrue: [cogit MoveR: ReceiverResultReg R: (reg :=
TempReg)]
ifFalse: [reg := ReceiverResultReg].
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits - 1
R: reg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: reg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: reg
ofSmallIntegerOopWithSingleTagBit: reg.
"Jump is NULL if above operation is not implemented, else return
the result"
jumpNegativeReceiver = 0
ifFalse:
[ReceiverResultReg > 7
ifTrue: [cogit MoveR: reg R:
ReceiverResultReg].
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label].
^CompletePrimitive!
-- _,,,^..^,,,_ best, Eliot
Hi Nicolas,
On Wed, Sep 4, 2019 at 2:35 PM Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote:
Hi Eliot, thanks. Yes, for now I let responsibility to image side (Smalltalk voidCogVMState), because it sounded complex to relink to interpreter... French say (but this might come from Sweden): do*n'**t cut** off **the** branch **you'**re **sitting** on*
:-).
I shall add the ability too store the setting in a bit stored in the image header then.
I have one favor to ask you. Can you rewrite InterpreterPrimitives>>#primitiveHighBit in the following way?
a) have all the special compiler versions separate and not nested. So
... self cppIf: #'__GNUC__' defined ifTrue: [... ^self]. self cppIf: #'_MSC_VER' defined ifTrue: [... ^self]. slow by-hand version here...
Why I want this is so that simulation reflects the real VM as much as possible. The way that the primitive is written right now is that when simulated it will always fail, and that means that the simulator doesn't really do what the real VM does.
Le mer. 4 sept. 2019 à 21:28, Eliot Miranda eliot.miranda@gmail.com a écrit :
Hi Nicolas,
this looks great! Thanks for your patience while I've reviewed
this. I do see that to implement CoInterpreter>>setPrimitiveDoMixedArithmetic: correctly we'll either have to discard JITed methods with primitives and remap context pcs. See e.g. CoInterpreterPrimitives>>primitiveVoidVMStateForMethod. I am happy to do this; the code needs a few changes anyway to make sure things still simulate. But you may be doing this anyway. If we step on each other's fingers then no worries. You can always commit your code over mine.
On Fri, Aug 30, 2019 at 5:04 PM commits@source.squeak.org wrote:
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox: http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2547.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2547 Author: nice Time: 31 August 2019, 2:02:51.22464 am UUID: 66e4c466-c54c-4035-a7fa-6078386cbc66 Ancestors: VMMaker.oscog-nice.2546
Fix genPrimitiveHighBit
We must not modify ReceiverResultReg when we CompletePrimitive (in case of negative receiver).
Hence, like in WIN64, we must better use TempReg.
=============== Diff against VMMaker.oscog-nice.2546 ===============
Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category 'primitive generators') ----- genPrimitiveHighBit
"Implementation notes: there are two reasons to use TempReg
-1) if primitive fails, ReceiverResultReg must remain unchanged
(we CompletePrimitive)
-2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel
X64. But Win64 uses R9
Normally, this should be backEnd dependent, but for now we have
a single 64bits target..."
| jumpNegativeReceiver | <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> "remove excess tag bits from the receiver oop"
cogit MoveR: ReceiverResultReg R: TempReg. self numSmallIntegerTagBits > 1 ifTrue:
[cogit OrCq: 1 << self numSmallIntegerTagBits -
1 R: TempReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: TempReg].
[cogit OrCq: 1 << self numSmallIntegerTagBits -
1 R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg]. "and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: TempReg
ofSmallIntegerOopWithSingleTagBit: TempReg.
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. "Jump is NULL if above operation is not implemented, else return the result" jumpNegativeReceiver = 0 ifFalse:
[cogit MoveR: TempReg R: ReceiverResultReg.
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
[cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg. cogit genPrimReturn. jumpNegativeReceiver jmpTarget: cogit Label]. ^CompletePrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentation>>genPrimitiveHighBitgenPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBitgenPrimitiveHighBit
| jumpNegativeReceiver |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits -
1 R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg.
"The jump instruction is NULL when backend does not really has a
jitted implementation: fallback to normal primitive"
jumpNegativeReceiver = 0 ifTrue: [^CompletePrimitive].
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label.
^UnimplementedPrimitive!
Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveHighBit
(in category 'primitive generators') -----
- genPrimitiveHighBit
"Implementation notes: same as super, but CLZ/BSR only work on
64bits for registers R0-R7 on Intel X64.
Normally, this should be backEnd dependent, but for now we have
a single 64bits target..."
| jumpNegativeReceiver reg |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
ReceiverResultReg > 7
ifTrue: [cogit MoveR: ReceiverResultReg R: (reg :=
TempReg)]
ifFalse: [reg := ReceiverResultReg].
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits -
1 R: reg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: reg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: reg
ofSmallIntegerOopWithSingleTagBit: reg.
"Jump is NULL if above operation is not implemented, else return
the result"
jumpNegativeReceiver = 0
ifFalse:
[ReceiverResultReg > 7
ifTrue: [cogit MoveR: reg R:
ReceiverResultReg].
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label].
^CompletePrimitive!
-- _,,,^..^,,,_ best, Eliot
Hi Eliot, Do you mean providing a default implementation that would for example loop instead of primitiveFail? If yes, shouldn't fallback code be guarded with cppIf: #'__GNUC__' defined not & #'_MSC_VER' defined not? Otherwise we may have a return in the middle of the function generating unreachable code warning, no?
Or should we use a simple cCode:inSmalltalk: somewhere (for example for simulating CLZ or BSR)? Can we control how the simulator should behave (emulate Clz BSR or fail)? Sorry to be ignorant in this domain...
Le jeu. 5 sept. 2019 à 02:08, Eliot Miranda eliot.miranda@gmail.com a écrit :
Hi Nicolas,
On Wed, Sep 4, 2019 at 2:35 PM Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote:
Hi Eliot, thanks. Yes, for now I let responsibility to image side (Smalltalk voidCogVMState), because it sounded complex to relink to interpreter... French say (but this might come from Sweden): do*n'**t cut** off **the** branch **you'**re **sitting** on*
:-).
I shall add the ability too store the setting in a bit stored in the image header then.
I have one favor to ask you. Can you rewrite InterpreterPrimitives>>#primitiveHighBit in the following way?
a) have all the special compiler versions separate and not nested. So
... self cppIf: #'__GNUC__' defined ifTrue: [... ^self]. self cppIf: #'_MSC_VER' defined ifTrue: [... ^self]. slow by-hand version here...
Why I want this is so that simulation reflects the real VM as much as possible. The way that the primitive is written right now is that when simulated it will always fail, and that means that the simulator doesn't really do what the real VM does.
Le mer. 4 sept. 2019 à 21:28, Eliot Miranda eliot.miranda@gmail.com a écrit :
Hi Nicolas,
this looks great! Thanks for your patience while I've reviewed
this. I do see that to implement CoInterpreter>>setPrimitiveDoMixedArithmetic: correctly we'll either have to discard JITed methods with primitives and remap context pcs. See e.g. CoInterpreterPrimitives>>primitiveVoidVMStateForMethod. I am happy to do this; the code needs a few changes anyway to make sure things still simulate. But you may be doing this anyway. If we step on each other's fingers then no worries. You can always commit your code over mine.
On Fri, Aug 30, 2019 at 5:04 PM commits@source.squeak.org wrote:
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox: http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2547.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2547 Author: nice Time: 31 August 2019, 2:02:51.22464 am UUID: 66e4c466-c54c-4035-a7fa-6078386cbc66 Ancestors: VMMaker.oscog-nice.2546
Fix genPrimitiveHighBit
We must not modify ReceiverResultReg when we CompletePrimitive (in case of negative receiver).
Hence, like in WIN64, we must better use TempReg.
=============== Diff against VMMaker.oscog-nice.2546 ===============
Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category 'primitive generators') ----- genPrimitiveHighBit
"Implementation notes: there are two reasons to use TempReg
-1) if primitive fails, ReceiverResultReg must remain unchanged
(we CompletePrimitive)
-2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel
X64. But Win64 uses R9
Normally, this should be backEnd dependent, but for now we have
a single 64bits target..."
| jumpNegativeReceiver | <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> "remove excess tag bits from the receiver oop"
cogit MoveR: ReceiverResultReg R: TempReg. self numSmallIntegerTagBits > 1 ifTrue:
[cogit OrCq: 1 << self numSmallIntegerTagBits -
1 R: TempReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: TempReg].
[cogit OrCq: 1 << self numSmallIntegerTagBits -
1 R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg]. "and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: TempReg
ofSmallIntegerOopWithSingleTagBit: TempReg.
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. "Jump is NULL if above operation is not implemented, else return the result" jumpNegativeReceiver = 0 ifFalse:
[cogit MoveR: TempReg R: ReceiverResultReg.
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
[cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg. cogit genPrimReturn. jumpNegativeReceiver jmpTarget: cogit Label]. ^CompletePrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentation>>genPrimitiveHighBitgenPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBitgenPrimitiveHighBit
| jumpNegativeReceiver |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits -
1 R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg.
"The jump instruction is NULL when backend does not really has
a jitted implementation: fallback to normal primitive"
jumpNegativeReceiver = 0 ifTrue: [^CompletePrimitive].
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label.
^UnimplementedPrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentationFor64BitSpur>>genPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBit
"Implementation notes: same as super, but CLZ/BSR only work on
64bits for registers R0-R7 on Intel X64.
Normally, this should be backEnd dependent, but for now we have
a single 64bits target..."
| jumpNegativeReceiver reg |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
ReceiverResultReg > 7
ifTrue: [cogit MoveR: ReceiverResultReg R: (reg :=
TempReg)]
ifFalse: [reg := ReceiverResultReg].
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits -
1 R: reg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: reg].
"and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: reg
ofSmallIntegerOopWithSingleTagBit: reg.
"Jump is NULL if above operation is not implemented, else
return the result"
jumpNegativeReceiver = 0
ifFalse:
[ReceiverResultReg > 7
ifTrue: [cogit MoveR: reg R:
ReceiverResultReg].
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label].
^CompletePrimitive!
-- _,,,^..^,,,_ best, Eliot
-- _,,,^..^,,,_ best, Eliot
For example, if we could fake a '__GNUC__' defined, then we could emulate in VMClass __builtin_clz: anInteger <doNotGenerate> anInteger < 0 ifTrue: [^0]. ^32 - anInteger highBit
similarly for clzll ^64 - ...
Le jeu. 5 sept. 2019 à 11:00, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> a écrit :
Hi Eliot, Do you mean providing a default implementation that would for example loop instead of primitiveFail? If yes, shouldn't fallback code be guarded with cppIf: #'__GNUC__' defined not & #'_MSC_VER' defined not? Otherwise we may have a return in the middle of the function generating unreachable code warning, no?
Or should we use a simple cCode:inSmalltalk: somewhere (for example for simulating CLZ or BSR)? Can we control how the simulator should behave (emulate Clz BSR or fail)? Sorry to be ignorant in this domain...
Le jeu. 5 sept. 2019 à 02:08, Eliot Miranda eliot.miranda@gmail.com a écrit :
Hi Nicolas,
On Wed, Sep 4, 2019 at 2:35 PM Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote:
Hi Eliot, thanks. Yes, for now I let responsibility to image side (Smalltalk voidCogVMState), because it sounded complex to relink to interpreter... French say (but this might come from Sweden): do*n'**t cut** off **the** branch **you'**re **sitting** on*
:-).
I shall add the ability too store the setting in a bit stored in the image header then.
I have one favor to ask you. Can you rewrite InterpreterPrimitives>>#primitiveHighBit in the following way?
a) have all the special compiler versions separate and not nested. So
... self cppIf: #'__GNUC__' defined ifTrue: [... ^self]. self cppIf: #'_MSC_VER' defined ifTrue: [... ^self]. slow by-hand version here...
Why I want this is so that simulation reflects the real VM as much as possible. The way that the primitive is written right now is that when simulated it will always fail, and that means that the simulator doesn't really do what the real VM does.
Le mer. 4 sept. 2019 à 21:28, Eliot Miranda eliot.miranda@gmail.com a écrit :
Hi Nicolas,
this looks great! Thanks for your patience while I've reviewed
this. I do see that to implement CoInterpreter>>setPrimitiveDoMixedArithmetic: correctly we'll either have to discard JITed methods with primitives and remap context pcs. See e.g. CoInterpreterPrimitives>>primitiveVoidVMStateForMethod. I am happy to do this; the code needs a few changes anyway to make sure things still simulate. But you may be doing this anyway. If we step on each other's fingers then no worries. You can always commit your code over mine.
On Fri, Aug 30, 2019 at 5:04 PM commits@source.squeak.org wrote:
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker Inbox: http://source.squeak.org/VMMakerInbox/VMMaker.oscog-nice.2547.mcz
==================== Summary ====================
Name: VMMaker.oscog-nice.2547 Author: nice Time: 31 August 2019, 2:02:51.22464 am UUID: 66e4c466-c54c-4035-a7fa-6078386cbc66 Ancestors: VMMaker.oscog-nice.2546
Fix genPrimitiveHighBit
We must not modify ReceiverResultReg when we CompletePrimitive (in case of negative receiver).
Hence, like in WIN64, we must better use TempReg.
=============== Diff against VMMaker.oscog-nice.2546 ===============
Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveHighBit (in category 'primitive generators') ----- genPrimitiveHighBit
"Implementation notes: there are two reasons to use TempReg
-1) if primitive fails, ReceiverResultReg must remain
unchanged (we CompletePrimitive)
-2) CLZ/BSR only work on 64bits for registers R0-R7 on Intel
X64. But Win64 uses R9
Normally, this should be backEnd dependent, but for now we
have a single 64bits target..."
| jumpNegativeReceiver | <var: #jumpNegativeReceiver type: #'AbstractInstruction *'> "remove excess tag bits from the receiver oop"
cogit MoveR: ReceiverResultReg R: TempReg. self numSmallIntegerTagBits > 1 ifTrue:
[cogit OrCq: 1 << self numSmallIntegerTagBits
- 1 R: TempReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: TempReg].
[cogit OrCq: 1 << self numSmallIntegerTagBits
- 1 R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg]. "and use the abstract cogit facility for case of single tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: TempReg
ofSmallIntegerOopWithSingleTagBit: TempReg.
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg. "Jump is NULL if above operation is not implemented, else return the result" jumpNegativeReceiver = 0 ifFalse:
[cogit MoveR: TempReg R: ReceiverResultReg.
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
[cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg. cogit genPrimReturn. jumpNegativeReceiver jmpTarget: cogit Label]. ^CompletePrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentation>>genPrimitiveHighBitgenPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBitgenPrimitiveHighBit
| jumpNegativeReceiver |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits
- 1 R: ReceiverResultReg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: ReceiverResultReg].
"and use the abstract cogit facility for case of single
tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: ReceiverResultReg
ofSmallIntegerOopWithSingleTagBit: ReceiverResultReg.
"The jump instruction is NULL when backend does not really has
a jitted implementation: fallback to normal primitive"
jumpNegativeReceiver = 0 ifTrue: [^CompletePrimitive].
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label.
^UnimplementedPrimitive!
Item was removed:
- ----- Method:
CogObjectRepresentationFor64BitSpur>>genPrimitiveHighBit (in category 'primitive generators') -----
- genPrimitiveHighBit
"Implementation notes: same as super, but CLZ/BSR only work on
64bits for registers R0-R7 on Intel X64.
Normally, this should be backEnd dependent, but for now we
have a single 64bits target..."
| jumpNegativeReceiver reg |
<var: #jumpNegativeReceiver type: #'AbstractInstruction *'>
"remove excess tag bits from the receiver oop"
ReceiverResultReg > 7
ifTrue: [cogit MoveR: ReceiverResultReg R: (reg :=
TempReg)]
ifFalse: [reg := ReceiverResultReg].
self numSmallIntegerTagBits > 1
ifTrue:
[cogit OrCw: 1 << self numSmallIntegerTagBits
- 1 R: reg.
cogit ArithmeticShiftRightCq: self
numSmallIntegerTagBits - 1 R: reg].
"and use the abstract cogit facility for case of single
tag-bit"
jumpNegativeReceiver := cogit genHighBitIn: reg
ofSmallIntegerOopWithSingleTagBit: reg.
"Jump is NULL if above operation is not implemented, else
return the result"
jumpNegativeReceiver = 0
ifFalse:
[ReceiverResultReg > 7
ifTrue: [cogit MoveR: reg R:
ReceiverResultReg].
cogit genConvertIntegerToSmallIntegerInReg:
ReceiverResultReg.
cogit genPrimReturn.
jumpNegativeReceiver jmpTarget: cogit Label].
^CompletePrimitive!
-- _,,,^..^,,,_ best, Eliot
-- _,,,^..^,,,_ best, Eliot
vm-dev@lists.squeakfoundation.org