About
*The only reason we assert needsFrame here is that in a frameless
method ReceiverResultReg must and does contain only self*
What if in frameless method we swap temporarily the ReceiverResultReg ?
I mean a work around like that for frameless methods :
SimpleStackBasedCogit >>genStorePop: popBoolean RemoteTemp: slotIndex At:
remoteTempIndex
*| tempReg |*
*needsFrame ifFalse: *
* [ **tempReg** := self allocateRegNotConflictingWith: (self
registerMaskFor: ClassReg and: ReceiverResultReg).*
*self MoveR: ReceiverResultReg R: tempReg ].*
popBoolean
ifTrue: [self PopR: ClassReg]
ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r:
FPReg R: ReceiverResultReg.
objectRepresentation
genStoreSourceReg: ClassReg
slotIndex: slotIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: needsFrame.
*needsFrame ifFalse: *
* [ **self MoveR: **tempReg** R:** ReceiverResultReg ].*
That's two extra instructions but compared to a stack frame creation it may
make sense.
Anyway it does not really matter I guess there are few frameless methods on
the SistaCogit.
2015-04-23 20:08 GMT+02:00 <commits(a)source.squeak.org>:
>
> Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
> http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1249.mcz
>
> ==================== Summary ====================
>
> Name: VMMaker.oscog-eem.1249
> Author: eem
> Time: 23 April 2015, 11:07:28.905 am
> UUID: 41e8dbc2-ed01-42d2-9155-eaf604510aaa
> Ancestors: VMMaker.oscog-eem.1248
>
> More commentary.
>
> =============== Diff against VMMaker.oscog-eem.1248 ===============
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genStorePop:LiteralVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean LiteralVariable: litVarIndex
> <inline: false>
> | association |
> + "The only reason we assert needsFrame here is that in a frameless
> method
> + ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> + trampoline expects the target of the store to be in
> ReceiverResultReg. So
> + in a frameless method we would have a conflict between the
> receiver and
> + the literal store, unless we we smart enough to realise that
> ReceiverResultReg
> + was unused after the literal variable store, unlikely given that
> methods
> + return self by default."
> self assert: needsFrame.
> association := self getLiteral: litVarIndex.
> self annotate: (self MoveCw: association R: ReceiverResultReg)
> objRef: association.
> objectRepresentation
> genEnsureObjInRegNotForwarded: ReceiverResultReg
> scratchReg: TempReg.
> popBoolean
> ifTrue: [self PopR: ClassReg]
> ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
> traceStores > 0 ifTrue:
> [self CallRT: ceTraceStoreTrampoline].
> ^objectRepresentation
> genStoreSourceReg: ClassReg
> slotIndex: ValueIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: needsFrame!
>
> Item was changed:
> ----- Method:
> SimpleStackBasedCogit>>genStorePop:MaybeContextReceiverVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
> <inline: false>
> | jmpSingle jmpDone |
> <var: #jmpSingle type: #'AbstractInstruction *'>
> <var: #jmpDone type: #'AbstractInstruction *'>
> + "The reason we need a frame here is that assigning to an inst var
> of a context may
> + involve wholesale reorganization of stack pages, and the only way
> to preserve the
> + execution state of an activation in that case is if it has a
> frame."
> self assert: needsFrame.
> self MoveMw: FoxMFReceiver r: FPReg R: ReceiverResultReg.
> objectRepresentation
> genLoadSlot: SenderIndex
> sourceReg: ReceiverResultReg
> destReg: TempReg.
> self MoveMw: 0 r: SPReg R: ClassReg.
> jmpSingle := objectRepresentation
> genJumpNotSmallIntegerInScratchReg: TempReg.
> self MoveCq: slotIndex R: SendNumArgsReg.
> self CallRT: ceStoreContextInstVarTrampoline.
> jmpDone := self Jump: 0.
> jmpSingle jmpTarget: self Label.
> traceStores > 0 ifTrue:
> [self CallRT: ceTraceStoreTrampoline].
> objectRepresentation
> genStoreSourceReg: ClassReg
> slotIndex: slotIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: true.
> jmpDone jmpTarget: self Label.
> popBoolean ifTrue:
> [self AddCq: objectMemory wordSize R: SPReg].
> ^0!
>
> Item was changed:
> ----- Method: SimpleStackBasedCogit>>genStorePop:RemoteTemp:At: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
> <inline: false>
> + "The only reason we assert needsFrame here is that in a frameless
> method
> + ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> + trampoline expects the target of the store to be in
> ReceiverResultReg. So
> + in a frameless method we would have a conflict between the
> receiver and
> + the temote temp store, unless we we smart enough to realise that
> + ReceiverResultReg was unused after the literal variable store,
> unlikely given
> + that methods return self by default."
> self assert: needsFrame.
> popBoolean
> ifTrue: [self PopR: ClassReg]
> ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
> self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r:
> FPReg R: ReceiverResultReg.
> traceStores > 0 ifTrue:
> [self CallRT: ceTraceStoreTrampoline].
> ^objectRepresentation
> genStoreSourceReg: ClassReg
> slotIndex: slotIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: needsFrame!
>
> Item was changed:
> ----- Method:
> StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in
> category 'bytecode generator support') -----
> genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
> <inline: false>
> | jmpSingle jmpDone valueReg |
> <var: #jmpSingle type: #'AbstractInstruction *'>
> <var: #jmpDone type: #'AbstractInstruction *'>
> + "The reason we need a frame here is that assigning to an inst var
> of a context may
> + involve wholesale reorganization of stack pages, and the only way
> to preserve the
> + execution state of an activation in that case is if it has a
> frame."
> self assert: needsFrame.
> self ssFlushUpThroughReceiverVariable: slotIndex.
> "Note that ReceiverResultReg remains live after both
> ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
> self ensureReceiverResultRegContainsSelf.
> self ssPop: 1.
> self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for the
> ceStoreCheck call in genStoreSourceReg:... below"
> self ssPush: 1.
> objectRepresentation
> genLoadSlot: SenderIndex
> sourceReg: ReceiverResultReg
> destReg: TempReg.
> valueReg := self ssStorePop: popBoolean toPreferredReg: ClassReg.
> valueReg ~= ClassReg ifTrue:
> [self MoveR: valueReg R: ClassReg].
> jmpSingle := objectRepresentation
> genJumpNotSmallIntegerInScratchReg: TempReg.
> self MoveCq: slotIndex R: SendNumArgsReg.
> self CallRT: ceStoreContextInstVarTrampoline.
> jmpDone := self Jump: 0.
> jmpSingle jmpTarget: self Label.
> traceStores > 0 ifTrue:
> [self MoveR: ClassReg R: TempReg.
> self CallRT: ceTraceStoreTrampoline].
> objectRepresentation
> genStoreSourceReg: ClassReg
> slotIndex: slotIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: true.
> jmpDone jmpTarget: self Label.
> ^0!
>
> Item was changed:
> ----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At:
> (in category 'bytecode generator support') -----
> genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
> <inline: false>
> | topReg topSpilled tempVectReg |
> + "The only reason we assert needsFrame here is that in a frameless
> method
> + ReceiverResultReg must and does contain only self, but the
> ceStoreCheck
> + trampoline expects the target of the store to be in
> ReceiverResultReg. So
> + in a frameless method we would have a conflict between the
> receiver and
> + the temote temp store, unless we we smart enough to realise that
> + ReceiverResultReg was unused after the literal variable store,
> unlikely given
> + that methods return self by default."
> self assert: needsFrame.
> optStatus isReceiverResultRegLive: false.
> "N.B. No need to check the stack for references because we
> generate code for
> remote temp loads that stores the result in a register, deferring
> only the register push."
> "Avoid store check for immediate values"
> (objectRepresentation isUnannotatableConstant: self ssTop) ifTrue:
> [ tempVectReg := self allocateAnyReg.
> self MoveMw: (self frameOffsetOfTemporary:
> remoteTempIndex) r: FPReg R: tempVectReg.
> self ssStorePop: popBoolean toReg: TempReg.
> traceStores > 0 ifTrue:
> [ tempVectReg = ReceiverResultReg ifFalse:
> [ self ssAllocateRequiredReg:
> ReceiverResultReg.
> optStatus isReceiverResultRegLive:
> false.
> self MoveR: tempVectReg R:
> ReceiverResultReg ].
> self CallRT: ceTraceStoreTrampoline].
> ^objectRepresentation
> genStoreImmediateInSourceReg: TempReg
> slotIndex: slotIndex
> destReg: tempVectReg].
> topReg := self allocateRegForStackTopEntryNotConflictingWith:
> (self registerMaskFor: ReceiverResultReg).
> self ssPop: 1.
> "for the ceStoreCheck call in genStoreSourceReg:... below"
> self ssAllocateCallReg: topReg and: ReceiverResultReg.
> self ssPush: 1.
> topSpilled := self ssTop spilled.
> self ssStorePop: (popBoolean or: [topSpilled]) toReg: topReg.
> popBoolean ifFalse:
> [topSpilled ifFalse: [self ssPop: 1].
> self ssPushRegister: topReg].
> self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r:
> FPReg R: ReceiverResultReg.
> traceStores > 0 ifTrue:
> [self MoveR: topReg R: TempReg.
> self CallRT: ceTraceStoreTrampoline].
> ^objectRepresentation
> genStoreSourceReg: topReg
> slotIndex: slotIndex
> destReg: ReceiverResultReg
> scratchReg: TempReg
> inFrame: needsFrame!
>
>
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1249.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1249
Author: eem
Time: 23 April 2015, 11:07:28.905 am
UUID: 41e8dbc2-ed01-42d2-9155-eaf604510aaa
Ancestors: VMMaker.oscog-eem.1248
More commentary.
=============== Diff against VMMaker.oscog-eem.1248 ===============
Item was changed:
----- Method: SimpleStackBasedCogit>>genStorePop:LiteralVariable: (in category 'bytecode generator support') -----
genStorePop: popBoolean LiteralVariable: litVarIndex
<inline: false>
| association |
+ "The only reason we assert needsFrame here is that in a frameless method
+ ReceiverResultReg must and does contain only self, but the ceStoreCheck
+ trampoline expects the target of the store to be in ReceiverResultReg. So
+ in a frameless method we would have a conflict between the receiver and
+ the literal store, unless we we smart enough to realise that ReceiverResultReg
+ was unused after the literal variable store, unlikely given that methods
+ return self by default."
self assert: needsFrame.
association := self getLiteral: litVarIndex.
self annotate: (self MoveCw: association R: ReceiverResultReg) objRef: association.
objectRepresentation
genEnsureObjInRegNotForwarded: ReceiverResultReg
scratchReg: TempReg.
popBoolean
ifTrue: [self PopR: ClassReg]
ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
traceStores > 0 ifTrue:
[self CallRT: ceTraceStoreTrampoline].
^objectRepresentation
genStoreSourceReg: ClassReg
slotIndex: ValueIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: needsFrame!
Item was changed:
----- Method: SimpleStackBasedCogit>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----
genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
<inline: false>
| jmpSingle jmpDone |
<var: #jmpSingle type: #'AbstractInstruction *'>
<var: #jmpDone type: #'AbstractInstruction *'>
+ "The reason we need a frame here is that assigning to an inst var of a context may
+ involve wholesale reorganization of stack pages, and the only way to preserve the
+ execution state of an activation in that case is if it has a frame."
self assert: needsFrame.
self MoveMw: FoxMFReceiver r: FPReg R: ReceiverResultReg.
objectRepresentation
genLoadSlot: SenderIndex
sourceReg: ReceiverResultReg
destReg: TempReg.
self MoveMw: 0 r: SPReg R: ClassReg.
jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
self MoveCq: slotIndex R: SendNumArgsReg.
self CallRT: ceStoreContextInstVarTrampoline.
jmpDone := self Jump: 0.
jmpSingle jmpTarget: self Label.
traceStores > 0 ifTrue:
[self CallRT: ceTraceStoreTrampoline].
objectRepresentation
genStoreSourceReg: ClassReg
slotIndex: slotIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: true.
jmpDone jmpTarget: self Label.
popBoolean ifTrue:
[self AddCq: objectMemory wordSize R: SPReg].
^0!
Item was changed:
----- Method: SimpleStackBasedCogit>>genStorePop:RemoteTemp:At: (in category 'bytecode generator support') -----
genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
<inline: false>
+ "The only reason we assert needsFrame here is that in a frameless method
+ ReceiverResultReg must and does contain only self, but the ceStoreCheck
+ trampoline expects the target of the store to be in ReceiverResultReg. So
+ in a frameless method we would have a conflict between the receiver and
+ the temote temp store, unless we we smart enough to realise that
+ ReceiverResultReg was unused after the literal variable store, unlikely given
+ that methods return self by default."
self assert: needsFrame.
popBoolean
ifTrue: [self PopR: ClassReg]
ifFalse: [self MoveMw: 0 r: SPReg R: ClassReg].
self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: ReceiverResultReg.
traceStores > 0 ifTrue:
[self CallRT: ceTraceStoreTrampoline].
^objectRepresentation
genStoreSourceReg: ClassReg
slotIndex: slotIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: needsFrame!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----
genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
<inline: false>
| jmpSingle jmpDone valueReg |
<var: #jmpSingle type: #'AbstractInstruction *'>
<var: #jmpDone type: #'AbstractInstruction *'>
+ "The reason we need a frame here is that assigning to an inst var of a context may
+ involve wholesale reorganization of stack pages, and the only way to preserve the
+ execution state of an activation in that case is if it has a frame."
self assert: needsFrame.
self ssFlushUpThroughReceiverVariable: slotIndex.
"Note that ReceiverResultReg remains live after both
ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
self ensureReceiverResultRegContainsSelf.
self ssPop: 1.
self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for the ceStoreCheck call in genStoreSourceReg:... below"
self ssPush: 1.
objectRepresentation
genLoadSlot: SenderIndex
sourceReg: ReceiverResultReg
destReg: TempReg.
valueReg := self ssStorePop: popBoolean toPreferredReg: ClassReg.
valueReg ~= ClassReg ifTrue:
[self MoveR: valueReg R: ClassReg].
jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
self MoveCq: slotIndex R: SendNumArgsReg.
self CallRT: ceStoreContextInstVarTrampoline.
jmpDone := self Jump: 0.
jmpSingle jmpTarget: self Label.
traceStores > 0 ifTrue:
[self MoveR: ClassReg R: TempReg.
self CallRT: ceTraceStoreTrampoline].
objectRepresentation
genStoreSourceReg: ClassReg
slotIndex: slotIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: true.
jmpDone jmpTarget: self Label.
^0!
Item was changed:
----- Method: StackToRegisterMappingCogit>>genStorePop:RemoteTemp:At: (in category 'bytecode generator support') -----
genStorePop: popBoolean RemoteTemp: slotIndex At: remoteTempIndex
<inline: false>
| topReg topSpilled tempVectReg |
+ "The only reason we assert needsFrame here is that in a frameless method
+ ReceiverResultReg must and does contain only self, but the ceStoreCheck
+ trampoline expects the target of the store to be in ReceiverResultReg. So
+ in a frameless method we would have a conflict between the receiver and
+ the temote temp store, unless we we smart enough to realise that
+ ReceiverResultReg was unused after the literal variable store, unlikely given
+ that methods return self by default."
self assert: needsFrame.
optStatus isReceiverResultRegLive: false.
"N.B. No need to check the stack for references because we generate code for
remote temp loads that stores the result in a register, deferring only the register push."
"Avoid store check for immediate values"
(objectRepresentation isUnannotatableConstant: self ssTop) ifTrue:
[ tempVectReg := self allocateAnyReg.
self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: tempVectReg.
self ssStorePop: popBoolean toReg: TempReg.
traceStores > 0 ifTrue:
[ tempVectReg = ReceiverResultReg ifFalse:
[ self ssAllocateRequiredReg: ReceiverResultReg.
optStatus isReceiverResultRegLive: false.
self MoveR: tempVectReg R: ReceiverResultReg ].
self CallRT: ceTraceStoreTrampoline].
^objectRepresentation
genStoreImmediateInSourceReg: TempReg
slotIndex: slotIndex
destReg: tempVectReg].
topReg := self allocateRegForStackTopEntryNotConflictingWith: (self registerMaskFor: ReceiverResultReg).
self ssPop: 1.
"for the ceStoreCheck call in genStoreSourceReg:... below"
self ssAllocateCallReg: topReg and: ReceiverResultReg.
self ssPush: 1.
topSpilled := self ssTop spilled.
self ssStorePop: (popBoolean or: [topSpilled]) toReg: topReg.
popBoolean ifFalse:
[topSpilled ifFalse: [self ssPop: 1].
self ssPushRegister: topReg].
self MoveMw: (self frameOffsetOfTemporary: remoteTempIndex) r: FPReg R: ReceiverResultReg.
traceStores > 0 ifTrue:
[self MoveR: topReg R: TempReg.
self CallRT: ceTraceStoreTrampoline].
^objectRepresentation
genStoreSourceReg: topReg
slotIndex: slotIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: needsFrame!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1248.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1248
Author: eem
Time: 23 April 2015, 10:43:29.344 am
UUID: ec950a22-b488-4bba-9520-24174b51b5ca
Ancestors: VMMaker.oscog-cb.1247
Commentary, and one assert added to Clément's changes.
=============== Diff against VMMaker.oscog-cb.1247 ===============
Item was changed:
----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable: (in category 'bytecode generator support') -----
genStorePop: popBoolean LiteralVariable: litVarIndex
<inline: false>
| topReg assocReg association |
+ "The only reason we assert needsFrame here is that in a frameless method
+ ReceiverResultReg must and does contain only self, but the ceStoreCheck
+ trampoline expects the target of the store to be in ReceiverResultReg. So
+ in a frameless method we would have a conflict between the receiver and
+ the literal store, unless we we smart enough to realise that ReceiverResultReg
+ was unused after the literal variable store, unlikely given that methods
+ return self by default."
+ self assert: needsFrame.
"N.B. No need to check the stack for references because we generate code for
literal variable loads that stores the result in a register, deferring only the register push."
association := self getLiteral: litVarIndex.
"Avoid store check for immediate values"
(objectRepresentation isUnannotatableConstant: self ssTop)
ifTrue:
[ assocReg := self allocateAnyReg.
self genMoveConstant: association R: assocReg.
objectRepresentation
genEnsureObjInRegNotForwarded: assocReg
scratchReg: TempReg.
self ssStorePop: popBoolean toReg: TempReg.
traceStores > 0 ifTrue:
[ assocReg = ReceiverResultReg ifFalse:
[ self ssAllocateRequiredReg: ReceiverResultReg.
optStatus isReceiverResultRegLive: false.
self MoveR: assocReg R: ReceiverResultReg ].
self CallRT: ceTraceStoreTrampoline].
^objectRepresentation
genStoreImmediateInSourceReg: TempReg
slotIndex: ValueIndex
destReg: assocReg ]
ifFalse: [ self assert: needsFrame. "because ReceiverResult reg is used for storeCheckTrampoline" ].
topReg := self allocateRegForStackTopEntryNotConflictingWith: (self registerMaskFor: ReceiverResultReg).
self ssStorePop: popBoolean toReg: topReg.
optStatus isReceiverResultRegLive: false.
self ssAllocateCallReg: ReceiverResultReg. "for ceStoreCheck call in genStoreSourceReg: has to be ReceiverResultReg"
self genMoveConstant: association R: ReceiverResultReg.
objectRepresentation genEnsureObjInRegNotForwarded: ReceiverResultReg scratchReg: TempReg.
traceStores > 0 ifTrue:
[self MoveR: topReg R: TempReg.
self CallRT: ceTraceStoreTrampoline].
^objectRepresentation
genStoreSourceReg: topReg
slotIndex: ValueIndex
destReg: ReceiverResultReg
scratchReg: TempReg
inFrame: needsFrame!
Item was changed:
----- Method: StackToRegisterMappingCogit>>ssAllocateCallReg:and: (in category 'simulation stack') -----
ssAllocateCallReg: requiredReg1 and: requiredReg2
+ "Allocate registers needed in a run-time call (i.e. flush uses of the
+ registers to the real stack). Since the run-time can smash any and
+ all caller-saved registers also flush all caller-saved registers."
self ssAllocateRequiredRegMask: (callerSavedRegMask
bitOr: ((self registerMaskFor: requiredReg1)
bitOr: (self registerMaskFor: requiredReg2)))
upThrough: simStackPtr!
Item was changed:
----- Method: StackToRegisterMappingCogit>>ssAllocateCallReg:and:and: (in category 'simulation stack') -----
ssAllocateCallReg: requiredReg1 and: requiredReg2 and: requiredReg3
+ "Allocate registers needed in a run-time call (i.e. flush uses of the
+ registers to the real stack). Since the run-time can smash any and
+ all caller-saved registers also flush all caller-saved registers."
self ssAllocateRequiredRegMask: (callerSavedRegMask
bitOr: ((self registerMaskFor: requiredReg1)
bitOr: ((self registerMaskFor: requiredReg2)
bitOr: (self registerMaskFor: requiredReg3))))
upThrough: simStackPtr!
Item was changed:
----- Method: StackToRegisterMappingCogit>>ssAllocateCallReg:and:and:and: (in category 'simulation stack') -----
ssAllocateCallReg: requiredReg1 and: requiredReg2 and: requiredReg3 and: requiredReg4
+ "Allocate registers needed in a run-time call (i.e. flush uses of the
+ registers to the real stack). Since the run-time can smash any and
+ all caller-saved registers also flush all caller-saved registers."
self ssAllocateRequiredRegMask: (callerSavedRegMask
bitOr: ((self registerMaskFor: requiredReg1)
bitOr: ((self registerMaskFor: requiredReg2)
bitOr: ((self registerMaskFor: requiredReg3)
bitOr: (self registerMaskFor: requiredReg4)))))
upThrough: simStackPtr!