[Vm-dev] VM Maker: VMMaker.oscog-eem.1275.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Apr 30 21:18:14 UTC 2015


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1275.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.1275
Author: eem
Time: 30 April 2015, 2:16:10.579 pm
UUID: c6fd91fc-f1cd-4ca7-93f6-38d581973d92
Ancestors: VMMaker.oscog-tfel.1274

Fix SimpleStackBasedCogit primitives for ARM; they
need an abstraqction for stack access on account
of there being a ret pc (x86) or not (ARM).

Fix regressions in genPrimitiveAsCharacter and
genInnerPrimitiveIdentityHash: where RetN: offset
had been replaced with 0.

Remove all the "self flag: 'currently caller pushes result'."
noise.  This was the right decision given
StackToRegisterMappingCogit.

Fix the store check trampoline for the
SimpleStackBasedCogit given the better
caller-saved-register logic there now.  Move some
reegister mask methods up the hierarchy as a result.

SimpleStackBasedCogit still crashes (in widthOfString:)
but gets much further than it has in recent months.

=============== Diff against VMMaker.oscog-tfel.1274 ===============

Item was changed:
  ----- Method: CoInterpreter>>ceNonLocalReturn: (in category 'trampolines') -----
  ceNonLocalReturn: returnValue
  	<api>
  	| closure home unwindContextOrNilOrZero ourContext frameToReturnTo contextToReturnTo theFP callerFP newPage |
  	<var: #frameToReturnTo type: #'char *'>
  	<var: #theFP type: #'char *'>
  	<var: #callerFP type: #'char *'>
  	<var: #newPage type: #'StackPage *'>
  	<var: #thePage type: #'StackPage *'>
  
  	"self shortPrintFrameAndCallers: framePointer.
  	self printOop: returnValue.
  	self halt."
  
  	self assert: (self isMachineCodeFrame: framePointer).
  	self assert: (self frameIsBlockActivation: framePointer).
  
  	"Since this is a block activation the closure is on the stack above any args and the frame."
  	closure := self pushedReceiverOrClosureOfFrame: framePointer.
  
  	home := nil.
  	"Walk the closure's lexical chain to find the context or frame to return from (home)."
  	[closure ~= objectMemory nilObject] whileTrue:
  		[home := objectMemory followField: ClosureOuterContextIndex ofObject: closure.
  		 closure := objectMemory followField: ClosureIndex ofObject: home].
  	"home is to be returned from provided there is no unwind-protect activation between
  	 this frame and home's sender.  Search for an unwind.  findUnwindThroughContext:
  	 will answer either the context for an unwind-protect activation or nilObj if the sender
  	 cannot be found or 0 if no unwind is found but the sender is.  We must update the
  	 current page's headFrame pointers to enable the search to identify widowed contexts
  	 correctly."
  	self externalWriteBackHeadFramePointers.
  	unwindContextOrNilOrZero := self findUnwindThroughContext: home.
  	unwindContextOrNilOrZero = objectMemory nilObject ifTrue:
  		["error: can't find home on chain; cannot return"
  		 ourContext := self ensureFrameIsMarried: framePointer SP: stackPointer.
  		 ^self externalCannotReturn: returnValue from: ourContext].
  	unwindContextOrNilOrZero ~= 0 ifTrue:
  		[^self externalAboutToReturn: returnValue through: unwindContextOrNilOrZero].
  
  	"Now we know home is on the sender chain.
  	 We could be returning to either a context or a frame.  Find out which."
  	contextToReturnTo := nil.
  	(self isMarriedOrWidowedContext: home)
  		ifTrue:
  			[self assert: (self checkIsStillMarriedContext: home currentFP: framePointer).
  			 theFP := self frameOfMarriedContext: home.
  			 (self isBaseFrame: theFP)
  				ifTrue:
  					[contextToReturnTo := self frameCallerContext: theFP]
  				ifFalse:
  					[frameToReturnTo := self frameCallerFP: theFP]]
  		ifFalse:
  			[contextToReturnTo := objectMemory fetchPointer: SenderIndex ofObject: home.
  			 ((objectMemory isContext: contextToReturnTo)
  			  and: [self isMarriedOrWidowedContext: contextToReturnTo]) ifTrue:
  				[self assert: (self checkIsStillMarriedContext: contextToReturnTo currentFP: framePointer).
  			 	 frameToReturnTo := self frameOfMarriedContext: contextToReturnTo.
  				 contextToReturnTo := nil]].
  
  	"If returning to a context we must make a frame for it unless it is dead."
  	contextToReturnTo ~= nil ifTrue:
  		[frameToReturnTo := self establishFrameForContextToReturnTo: contextToReturnTo.
  		 frameToReturnTo == 0 ifTrue:
  			["error: home's sender is dead; cannot return"
  			 ourContext := self ensureFrameIsMarried: framePointer SP: stackPointer.
  			 ^self externalCannotReturn: returnValue from: ourContext]].
  
  	"Now we have a frame to return to.  If it is on a different page we must
  	 free intervening pages and nil out intervening contexts.  We must free
  	 intervening stack pages because if we leave the pages to be divorced
  	 then their contexts will be divorced with intact senders and instruction
  	 pointers.  This code is similar to primitiveTerminateTo."
  	self assert: stackPages pageListIsWellFormed.
  	newPage := stackPages stackPageFor: frameToReturnTo.
  	newPage ~~ stackPage ifTrue:
  		[| currentCtx thePage nextCntx |
  		 currentCtx := self frameCallerContext: stackPage baseFP.
  		 self assert: (objectMemory isContext: currentCtx).
  		 stackPages freeStackPage: stackPage.
  		 [self assert: (objectMemory isContext: currentCtx).
  		  (self isMarriedOrWidowedContext: currentCtx)
  		   and: [(stackPages stackPageFor: (theFP := self frameOfMarriedContext: currentCtx)) = newPage]] whileFalse:
  			[(self isMarriedOrWidowedContext: currentCtx)
  				ifTrue:
  					[thePage := stackPages stackPageFor: theFP.
  					 currentCtx := self frameCallerContext: thePage baseFP.
  					 stackPages freeStackPage: thePage]
  				ifFalse:
  					[nextCntx := objectMemory fetchPointer: SenderIndex ofObject: currentCtx.
  					 self markContextAsDead: currentCtx.
  					 currentCtx := nextCntx]].
  		 self setStackPageAndLimit: newPage.
  		 stackPointer := stackPage headSP.
  		 framePointer := stackPage headFP].
  
  	"Two cases.  Returning to the top frame or an interior frame.  The
  	 top frame has its instruction pointer on top of stack.  An interior
  	 frame has its instruction pointer in the caller frame. We need to
  	 peel back any frames on the page until we get to the correct frame."
- 	self flag: 'currently caller pushes result'. "(in machine code)"
  	framePointer = frameToReturnTo
  		ifTrue:
  			[instructionPointer := self popStack]
  		ifFalse:
  			[[callerFP := framePointer.
  			  framePointer := self frameCallerFP: framePointer.
  			  framePointer ~~ frameToReturnTo] whileTrue.
  			 instructionPointer := (self frameCallerSavedIP: callerFP) asUnsignedInteger.
  			 stackPointer := (self frameCallerSP: callerFP)].
  	^self return: returnValue toExecutive: false!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveIdentityHash: (in category 'primitive generators') -----
  genInnerPrimitiveIdentityHash: retNoffset
  	| jumpImm jumpSI jumpNotSet ret |
  	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpImm type: #'AbstractInstruction *'>
  	<var: #jumpNotSet type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: ClassReg.
  	jumpImm := self genJumpImmediateInScratchReg: ClassReg.
  	self genGetHashFieldNonImmOf: ReceiverResultReg asSmallIntegerInto: TempReg.
  	cogit CmpCq: ConstZero R: TempReg.
  	jumpNotSet := cogit JumpZero: 0.
  	cogit MoveR: TempReg R: ReceiverResultReg.
+ 	ret := cogit RetN: retNoffset.
- 	ret := cogit RetN: 0.
  	jumpImm jmpTarget: (cogit MoveR: ReceiverResultReg R: ClassReg).
  	jumpSI := self genJumpSmallIntegerInScratchReg: ClassReg.
  	jumpSI jmpTarget: ret.
  	self genConvertCharacterToSmallIntegerInReg: ReceiverResultReg.
  	cogit Jump: ret.
  	jumpNotSet jmpTarget: cogit Label.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>compileInterpreterPrimitive: (in category 'primitive generators') -----
  compileInterpreterPrimitive: primitiveRoutine
  	"Compile a call to an interpreter primitive.  Call the C routine with the
  	 usual stack-switching dance, test the primFailCode and then either
  	 return on success or continue to the method body."
  	<var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
  	| flags jmp jmpSamplePrim retry continuePostSamplePrim jmpSampleNonPrim continuePostSampleNonPrim |
  	<var: #jmp type: #'AbstractInstruction *'>
  	<var: #retry type: #'AbstractInstruction *'>
  	<var: #jmpSamplePrim type: #'AbstractInstruction *'>
  	<var: #continuePostSamplePrim type: #'AbstractInstruction *'>
  	<var: #jmpSampleNonPrim type: #'AbstractInstruction *'>
  	<var: #continuePostSampleNonPrim type: #'AbstractInstruction *'>
  
  	"Save processor fp, sp and return pc in the interpreter's frame stack and instruction pointers"
  	self genExternalizePointersForPrimitiveCall.
  	"Switch to the C stack."
  	self genLoadCStackPointersForPrimCall.
  
  	flags := coInterpreter primitivePropertyFlags: primitiveIndex.
  	(flags anyMask: PrimCallDoNotJIT) ifTrue:
  		[^ShouldNotJIT].
  
  	(flags anyMask: PrimCallCollectsProfileSamples) ifTrue:
  		["Test nextProfileTick for being non-zero and call checkProfileTick if so"
  		objectMemory wordSize = 4
  			ifTrue:
  				[self MoveAw: coInterpreter nextProfileTickAddress R: TempReg.
  				 self MoveAw: coInterpreter nextProfileTickAddress + objectMemory wordSize R: ClassReg.
  				 self OrR: TempReg R: ClassReg]
  			ifFalse:
  				[self MoveAw: coInterpreter nextProfileTickAddress R: TempReg.
  				 self CmpCq: 0 R: TempReg].
  		"If set, jump to record sample call."
  		jmpSampleNonPrim := self JumpNonZero: 0.
  		continuePostSampleNonPrim := self Label].
  
  	"Old full prim trace is in VMMaker-eem.550 and prior"
  	self recordPrimTrace ifTrue:
  		[self genFastPrimTraceUsing: ClassReg and: SendNumArgsReg].
  
  	"Clear the primFailCode and set argumentCount"
  	retry := self MoveCq: 0 R: TempReg.
  	self MoveR: TempReg Aw: coInterpreter primFailCodeAddress.
  	methodOrBlockNumArgs ~= 0 ifTrue:
  		[self MoveCq: methodOrBlockNumArgs R: TempReg].
  	self MoveR: TempReg Aw: coInterpreter argumentCountAddress.
  
  	"If required, set primitiveFunctionPointer and newMethod"
  	(flags anyMask: PrimCallNeedsPrimitiveFunction) ifTrue:
  		[self MoveCw: primitiveRoutine asInteger R: TempReg.
  		 self MoveR: TempReg Aw: coInterpreter primitiveFunctionPointerAddress].
  	(flags anyMask: PrimCallNeedsNewMethod+PrimCallMayCallBack) ifTrue:
  		["The ceActivateFailingPrimitiveMethod: machinery can't handle framelessness."
  		 (flags anyMask: PrimCallMayCallBack) ifTrue:
  			[needsFrame := true].
  		 methodLabel addDependent:
  			(self annotateAbsolutePCRef:
  				(self MoveCw: methodLabel asInteger R: ClassReg)).
  		 self MoveMw: (self offset: CogMethod of: #methodObject) r: ClassReg R: TempReg.
  		 self MoveR: TempReg Aw: coInterpreter newMethodAddress].
  
  	"Invoke the primitive"
  	self PrefetchAw: coInterpreter primFailCodeAddress.
  	(flags anyMask: PrimCallMayCallBack)
  		ifTrue: "Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode."
  			["On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders
  			  are found. So insist on PrimCallNeedsPrimitiveFunction being set too."
  			 self assert: (flags anyMask: PrimCallNeedsPrimitiveFunction).
  			 backEnd genSubstituteReturnAddress:
  				((flags anyMask: PrimCallCollectsProfileSamples)
  					ifTrue: [cePrimReturnEnterCogCodeProfiling]
  					ifFalse: [cePrimReturnEnterCogCode]).
  			 self JumpFullRT: primitiveRoutine asInteger.
  			 primInvokeLabel := self Label.
  			 jmp := jmpSamplePrim := continuePostSamplePrim := nil]
  		ifFalse:
  			["Call the C primitive routine."
  			self CallFullRT: primitiveRoutine asInteger.
  			primInvokeLabel := self Label.
  			(flags anyMask: PrimCallCollectsProfileSamples) ifTrue:
  				[self assert: (flags anyMask: PrimCallNeedsNewMethod).
  				"Test nextProfileTick for being non-zero and call checkProfileTick if so"
  				objectMemory wordSize = 4
  					ifTrue:
  						[self MoveAw: coInterpreter nextProfileTickAddress R: TempReg.
  						 self MoveAw: coInterpreter nextProfileTickAddress + objectMemory wordSize R: ClassReg.
  						 self OrR: TempReg R: ClassReg]
  					ifFalse:
  						[self MoveAw: coInterpreter nextProfileTickAddress R: TempReg.
  						 self CmpCq: 0 R: TempReg].
  				"If set, jump to record sample call."
  				jmpSamplePrim := self JumpNonZero: 0.
  				continuePostSamplePrim := self Label].
  			objectRepresentation maybeCompileRetry: retry onPrimitiveFail: primitiveIndex.
  			self maybeCompileAllocFillerCheck.
  			"Switch back to the Smalltalk stack.  Stack better be in either of these two states:
  				success:	stackPointer ->	result (was receiver)
  											arg1
  											...
  											argN
  											return pc
  				failure:						receiver
  											arg1
  											...
  							stackPointer ->	argN
  											return pc
  			In either case we can push the instructionPointer or load it into the LinkRegister to reestablish the return pc"
  			self MoveAw: coInterpreter instructionPointerAddress
  				R: (backEnd hasLinkRegister ifTrue: [LinkReg] ifFalse: [ClassReg]).
  			backEnd genLoadStackPointers.
  			"Test primitive failure"
  			self MoveAw: coInterpreter primFailCodeAddress R: TempReg.
  			backEnd hasLinkRegister ifFalse: [self PushR: ClassReg]. "Restore return pc on CISCs"
  			self flag: 'ask concrete code gen if move sets condition codes?'.
  			self CmpCq: 0 R: TempReg.
  			jmp := self JumpNonZero: 0.
  			"Fetch result from stack"
  			self MoveMw: (backEnd hasLinkRegister ifTrue: [0] ifFalse: [objectMemory wordSize])
  				r: SPReg
  				R: ReceiverResultReg.
- 			self flag: 'currently caller pushes result'.
  			self RetN: objectMemory wordSize].	"return to caller, popping receiver"
  
  	(flags anyMask: PrimCallCollectsProfileSamples) ifTrue:
  		["The sample is collected by cePrimReturnEnterCogCode for external calls"
  		jmpSamplePrim notNil ifTrue:
  			["Call ceCheckProfileTick: to record sample and then continue."
  			jmpSamplePrim jmpTarget: self Label.
  			self assert: (flags anyMask: PrimCallNeedsNewMethod).
  			self CallFullRT: (self cCode: [#ceCheckProfileTick asUnsignedLong]
  							   inSmalltalk: [self simulatedTrampolineFor: #ceCheckProfileTick]).
  			"reenter the post-primitive call flow"
  			self Jump: continuePostSamplePrim].
  		"Null newMethod and call ceCheckProfileTick: to record sample and then continue.
  		 ceCheckProfileTick will map null/0 to coInterpreter nilObject"
  		jmpSampleNonPrim jmpTarget: self Label.
  		self MoveCq: 0 R: TempReg.
  		self MoveR: TempReg Aw: coInterpreter newMethodAddress.
  		self CallFullRT: (self cCode: [#ceCheckProfileTick asUnsignedLong]
  						   inSmalltalk: [self simulatedTrampolineFor: #ceCheckProfileTick]).
  		"reenter the post-primitive call flow"
  		self Jump: continuePostSampleNonPrim].
  
  	jmp notNil ifTrue:
  		["Jump to restore of receiver reg and proceed to frame build for failure."
  		 jmp jmpTarget: self Label.
  		 "Restore receiver reg from stack.  If on RISCs ret pc is in LinkReg, if on CISCs ret pc is on stack."
  		 self MoveMw: objectMemory wordSize * (methodOrBlockNumArgs + (backEnd hasLinkRegister ifTrue: [0] ifFalse: [1]))
  			r: SPReg
  			R: ReceiverResultReg].
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
  genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
  	<var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
  	| jumpFailClass jumpFailAlloc jumpFailCheck jumpImmediate jumpNonInt doOp fail |
  	<var: #jumpFailClass type: #'AbstractInstruction *'>
  	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
  	<var: #jumpNonInt type: #'AbstractInstruction *'>
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpFailCheck type: #'AbstractInstruction *'>
  	<var: #doOp type: #'AbstractInstruction *'>
  	<var: #fail type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	self MoveR: TempReg R: ClassReg.
  	jumpImmediate := objectRepresentation genJumpImmediateInScratchReg: TempReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: SendNumArgsReg.
  	objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
  	jumpFailClass := self JumpNonZero: 0.
  	objectRepresentation genGetDoubleValueOf: ClassReg into: DPFPReg1.
  	doOp := self Label.
  	preOpCheckOrNil ifNotNil:
  		[jumpFailCheck := self perform: preOpCheckOrNil with: DPFPReg0 with: DPFPReg1].
  	self gen: arithmeticOperator operand: DPFPReg1 operand: DPFPReg0.
  	jumpFailAlloc := objectRepresentation
  					genAllocFloatValue: DPFPReg0
  					into: SendNumArgsReg
  					scratchReg: ClassReg
  					scratchReg: TempReg.
  	self MoveR: SendNumArgsReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpImmediate jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg].
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  	self ConvertR: ClassReg Rd: DPFPReg1.
  	self Jump: doOp.
  	jumpFailAlloc jmpTarget: self Label.
  	self compileFallbackToInterpreterPrimitive.
  	fail := self Label.
  	jumpFailClass jmpTarget: fail.
  	preOpCheckOrNil ifNotNil:
  		[jumpFailCheck jmpTarget: fail].
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt jmpTarget: fail].
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genDoubleComparison:invert: (in category 'primitive generators') -----
  genDoubleComparison: jumpOpcodeGenerator invert: invertComparison
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
  	<var: #jumpOpcodeGenerator declareC: 'AbstractInstruction *(*jumpOpcodeGenerator)(void *)'>
  	| jumpFail jumpImmediate jumpNonInt jumpCond compare |
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpNonInt type: #'AbstractInstruction *'>
  	<var: #jumpCond type: #'AbstractInstruction *'>
  	<var: #compare type: #'AbstractInstruction *'>
  	<var: #jumpFail type: #'AbstractInstruction *'>
  
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	self MoveR: TempReg R: ClassReg.
  	jumpImmediate := objectRepresentation genJumpImmediateInScratchReg: TempReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: SendNumArgsReg.
  	objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
  	jumpFail := self JumpNonZero: 0.
  	objectRepresentation genGetDoubleValueOf: ClassReg into: DPFPReg1.
  	invertComparison "May need to invert for NaNs"
  		ifTrue: [compare := self CmpRd: DPFPReg0 Rd: DPFPReg1]
  		ifFalse: [compare := self CmpRd: DPFPReg1 Rd: DPFPReg0].
  	jumpCond := self perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"
  	self genMoveFalseR: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpCond jmpTarget: (self genMoveTrueR: ReceiverResultReg).
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self RetN: objectMemory wordSize * 2.
  	jumpImmediate jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg].
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  	self ConvertR: ClassReg Rd: DPFPReg1.
  	self Jump: compare.
  	jumpFail jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt jmpTarget: jumpFail getJmpTarget].
  	^0!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>genLoadArgAtDepth:into: (in category 'primitive generators') -----
+ genLoadArgAtDepth: n into: reg
+ 	"Load an argument at depth from top-of-stack (0 relative) into a register.
+ 	 The actual offset depends on whether there's a link register or not."
+ 	self MoveMw: (backEnd hasLinkRegister ifTrue: [n] ifFalse: [n + 1]) * objectMemory wordSize
+ 		r: SPReg
+ 		R: reg!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimReturnEnterCogCodeEnilopmart: (in category 'initialization') -----
  genPrimReturnEnterCogCodeEnilopmart: profiling
  	"Generate the substitute return code for an external or FFI primitive call.
  	 On success simply return, extracting numArgs from newMethod.
  	 On primitive failure call ceActivateFailingPrimitiveMethod: newMethod."
  	| jmpSample continuePostSample jmpFail |
  	<var: #jmpSample type: #'AbstractInstruction *'>
  	<var: #continuePostSample type: #'AbstractInstruction *'>
  	<var: #jmpFail type: #'AbstractInstruction *'>
  	opcodeIndex := 0.
  
  	profiling ifTrue:
  		["Test nextProfileTick for being non-zero and call checkProfileTick: if so.
  		  N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves."
  		objectMemory wordSize = 4
  			ifTrue:
  				[self MoveAw: coInterpreter nextProfileTickAddress R: TempReg.
  				 self MoveAw: coInterpreter nextProfileTickAddress + objectMemory wordSize R: ClassReg.
  				 self OrR: TempReg R: ClassReg]
  			ifFalse:
  				[self MoveAw: coInterpreter nextProfileTickAddress R: TempReg.
  				 self CmpCq: 0 R: TempReg].
  		"If set, jump to record sample call."
  		jmpSample := self JumpNonZero: 0.
  		continuePostSample := self Label].
  
  	self maybeCompileAllocFillerCheck.
  
  	"Test primitive failure"
  	self MoveAw: coInterpreter primFailCodeAddress R: TempReg.
  	self flag: 'ask concrete code gen if move sets condition codes?'.
  	self CmpCq: 0 R: TempReg.
  	jmpFail := self JumpNonZero: 0.
  
  	"Switch back to the Smalltalk stack.  Stack better be in either of these two states:
  		success:	stackPointer	->	result (was receiver)
  										arg1
  										...
  										argN
  										return pc
  		failure:							receiver
  										arg1
  										...
  					stackPointer	->	argN
  										return pc
  	We push the instructionPointer to reestablish the return pc in the success case,
  	but leave it to ceActivateFailingPrimitiveMethod: to do so in the failure case."
  
  	backEnd hasLinkRegister
  		ifTrue:
  			[backEnd genLoadStackPointers.											"Switch back to Smalltalk stack."
  			 backEnd hasPCRegister
  				ifTrue:
  					[self PopR: ReceiverResultReg.										"Pop result from stack"
  					 self MoveAw: coInterpreter instructionPointerAddress R: PCReg]	"Return"
  				ifFalse:
  					[self MoveMw: 0 r: SPReg R: ReceiverResultReg.						"Fetch result from stack"
  					 self MoveAw: coInterpreter instructionPointerAddress R: LinkReg.	"Get ret pc"
  					 self RetN: objectMemory wordSize]]								"Return, popping result from stack"
  		ifFalse:
  			[self MoveAw: coInterpreter instructionPointerAddress R: ClassReg.	"Get return pc"
  			 backEnd genLoadStackPointers.									"Switch back to Smalltalk stack."
  			 self MoveMw: 0 r: SPReg R: ReceiverResultReg.						"Fetch result from stack"
  			 self MoveR: ClassReg Mw: 0 r: SPReg.								"Restore return pc"
  			 self RetN: 0].														"Return, popping result from stack"
  
  	"Primitive failed.  Invoke C code to build the frame and continue."
  	jmpFail jmpTarget: (self MoveAw: coInterpreter newMethodAddress R: SendNumArgsReg).
  	"Reload sp with CStackPointer; easier than popping args of checkProfileTick."
  	self MoveAw: self cStackPointerAddress R: SPReg.
  	self 
  		compileCallFor: #ceActivateFailingPrimitiveMethod:
  		numArgs: 1
  		arg: SendNumArgsReg
  		arg: nil
  		arg: nil
  		arg: nil
  		resultReg: nil
  		saveRegs: false.
  
  	"On Spur ceActivateFailingPrimitiveMethod: may retry the primitive and return if successful.
  	 So continue by returning to the caller.
  	 Switch back to the Smalltalk stack.  Stack should be in this state:
  				success:	stackPointer ->	result (was receiver)
  											arg1
  											...
  											argN
  											return pc
  	 We can push the instructionPointer or load it into the LinkRegister to reestablish the return pc"
  	self MoveAw: coInterpreter instructionPointerAddress
  		R: (backEnd hasLinkRegister ifTrue: [LinkReg] ifFalse: [ClassReg]).
  	backEnd genLoadStackPointers.
  	backEnd hasLinkRegister
  		ifTrue:
  			[self MoveMw: 0 r: SPReg R: ReceiverResultReg]	"Fetch result from stack"
  		ifFalse:
  			[self MoveMw: objectMemory wordSize r: SPReg R: ReceiverResultReg.	"Fetch result from stack"
  			 self PushR: ClassReg].											"Restore return pc on CISCs"
- 	self flag: 'currently caller pushes result'.
  	self RetN: objectMemory wordSize.	"return to caller, popping receiver"
  
  	profiling ifTrue:
  		["Call ceCheckProfileTick: to record sample and then continue.  newMethod
  		 should be up-to-date.  Need to save and restore the link reg around this call."
  		 jmpSample jmpTarget: self Label.
  		 backEnd saveAndRestoreLinkRegAround:
  			[self CallFullRT: (self cCode: '(unsigned long)ceCheckProfileTick'
  						inSmalltalk: [self simulatedTrampolineFor: #ceCheckProfileTick])].
  		 self Jump: continuePostSample]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveAdd (in category 'primitive generators') -----
  genPrimitiveAdd
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
  	| jumpNotSI jumpOvfl |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpOvfl type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ClassReg.
  	self MoveR: ReceiverResultReg R: TempReg.
  	self AddR: ClassReg R: TempReg.
  	jumpOvfl := self JumpOverflow: 0.
  	self MoveR: TempReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpOvfl jmpTarget: (jumpNotSI jmpTarget: self Label).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveAsCharacter (in category 'primitive generators') -----
  genPrimitiveAsCharacter
  	| na r |
  	na := coInterpreter argumentCountOf: methodObj.
  	na <= 1 ifTrue:
  		[na = 1 ifTrue:
+ 			[self genLoadArgAtDepth: 0 into: Arg0Reg].
- 			[self MoveMw: objectMemory wordSize r: SPReg R: Arg0Reg].
  		 (r := objectRepresentation
+ 				genInnerPrimitiveAsCharacter: (self primRetNOffsetFor: na)
- 				genInnerPrimitiveAsCharacter: 0
  				inReg: (na = 0 ifTrue: [ReceiverResultReg] ifFalse: [Arg0Reg])) < 0 ifTrue:
  			[^r]].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveAsFloat (in category 'primitive generators') -----
  genPrimitiveAsFloat
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		return address"
  	| jumpFailAlloc |
  	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
  	self MoveR: ReceiverResultReg R: ClassReg.
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  	self ConvertR: ClassReg Rd: DPFPReg0.
  	jumpFailAlloc := objectRepresentation
  					genAllocFloatValue: DPFPReg0
  					into: SendNumArgsReg
  					scratchReg: ClassReg
  					scratchReg: TempReg.
  	self MoveR: SendNumArgsReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 0).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize.
  	jumpFailAlloc jmpTarget: self Label.
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveAt (in category 'primitive generators') -----
  genPrimitiveAt
  	| r |
+ 	self genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	(r := objectRepresentation genInnerPrimitiveAt: (self primRetNOffsetFor: 1)) < 0 ifTrue:
- 	self MoveMw: objectMemory wordSize r: SPReg R: Arg0Reg.
- 	(r := objectRepresentation genInnerPrimitiveAt: objectMemory wordSize * 2) < 0 ifTrue:
  		[^r].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveAtPut (in category 'primitive generators') -----
  genPrimitiveAtPut
  	| r |
+ 	self genLoadArgAtDepth: 1 into: Arg0Reg.
+ 	self genLoadArgAtDepth: 0 into: Arg1Reg.
+ 	((r := objectRepresentation genInnerPrimitiveAtPut: (self primRetNOffsetFor: 2)) < 0
- 	self MoveMw: objectMemory wordSize * 2 r: SPReg R: Arg0Reg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: Arg1Reg.
- 	((r := objectRepresentation genInnerPrimitiveAtPut: objectMemory wordSize * 3) < 0
  	 and: [r ~= UnimplementedPrimitive]) ifTrue:
  		[^r].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveBitAnd (in category 'primitive generators') -----
  genPrimitiveBitAnd
  	| jumpNotSI |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: Arg0Reg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	"Whether the SmallInteger tags are zero or non-zero, anding them together will preserve them."
  	self AndR: ClassReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpNotSI jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveBitOr (in category 'primitive generators') -----
  genPrimitiveBitOr
  	| jumpNotSI |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	"Whether the SmallInteger tags are zero or non-zero, oring them together will preserve them."
  	self OrR: ClassReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpNotSI jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveBitShift (in category 'primitive generators') -----
  genPrimitiveBitShift
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address
  
  	rTemp := ArgOffset(SP)
  	rClass := tTemp
  	rTemp := rTemp & 1
  	jz nonInt
  	rClass >>= 1
  	cmp 0,rClass
  	jge neg
  	cmp 31,rClass // numSmallIntegerBits, jge for sign
  	jge tooBig
  	rTemp := rReceiver
  	rTemp <<= rClass
  	rTemp >>= rClass (arithmetic)
  	cmp rTemp,rReceiver
  	jnz ovfl
  	rReceiver := rReceiver - 1
  	rReceiver := rReceiver <<= rClass
  	rReceiver := rReceiver + 1
  	ret
  neg:
  	rClass := 0 - rClass
  	cmp 31,rClass
  	jge inRange
  	rClass := 31
  inRange
  	rReceiver := rReceiver >>= rClass.
  	rReceiver := rReceiver | 1.
  	ret
  ovfl
  tooBig
  nonInt:
  	fail"
  	| jumpNotSI jumpOvfl jumpNegative jumpTooBig jumpInRange |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpOvfl type: #'AbstractInstruction *'>
  	<var: #jumpNegative type: #'AbstractInstruction *'>
  	<var: #jumpTooBig type: #'AbstractInstruction *'>
  	<var: #jumpInRange type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
  	(self lastOpcode setsConditionCodesFor: JumpNegative) ifFalse:
  		[self CmpCq: 0 R: ClassReg]. "N.B. FLAGS := ClassReg - 0"
  	jumpNegative := self JumpNegative: 0.
  	self CmpCq: objectRepresentation numSmallIntegerBits R: ClassReg. "N.B. FLAGS := ClassReg - 31"
  	jumpTooBig := self JumpGreaterOrEqual: 0.
  	self MoveR: ReceiverResultReg R: TempReg.
  	self LogicalShiftLeftR: ClassReg R: TempReg.
  	self ArithmeticShiftRightR: ClassReg R: TempReg.
  	self CmpR: TempReg R: ReceiverResultReg. "N.B. FLAGS := RRReg - TempReg"
  	jumpOvfl := self JumpNonZero: 0.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ReceiverResultReg.
  	self LogicalShiftLeftR: ClassReg R: ReceiverResultReg.
  	objectRepresentation genAddSmallIntegerTagsTo: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self RetN: objectMemory wordSize * 2.
  	jumpNegative jmpTarget: (self NegateR: ClassReg).
  	self CmpCq: objectRepresentation numSmallIntegerBits R: ClassReg. "N.B. FLAGS := ClassReg - 31"
  	jumpInRange := self JumpLessOrEqual: 0.
  	self MoveCq: objectRepresentation numSmallIntegerBits R: ClassReg.
  	jumpInRange jmpTarget: (self ArithmeticShiftRightR: ClassReg R: ReceiverResultReg).
  	objectRepresentation genSetSmallIntegerTagsIn: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self RetN: objectMemory wordSize * 2.
  	jumpNotSI jmpTarget: (jumpTooBig jmpTarget: (jumpOvfl jmpTarget: self Label)).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveBitXor (in category 'primitive generators') -----
  genPrimitiveBitXor
  	| jumpNotSI |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into:TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	"Clear one or the other tag so that xoring will preserve them."
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ClassReg.
  	self XorR: ClassReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpNotSI jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveCharacterValue (in category 'primitive generators') -----
  genPrimitiveCharacterValue
  	| r |
+ 	(r := objectRepresentation genInnerPrimitiveCharacterValue: (self primRetNOffsetFor: 0)) < 0 ifTrue:
- 	(r := objectRepresentation genInnerPrimitiveCharacterValue: objectMemory wordSize) < 0 ifTrue:
  		[^r].
  	^r = UnfailingPrimitive
  		ifTrue: [0]
  		ifFalse: [self compileFallbackToInterpreterPrimitive]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveClass (in category 'primitive generators') -----
  genPrimitiveClass
  	"Stack looks like
  		receiver (also in ReceiverResultReg)
  		return address"
  	(objectRepresentation
  			genGetClassObjectOf: ReceiverResultReg
  			into: ReceiverResultReg
  			scratchReg: TempReg
  			instRegIsReceiver: methodOrBlockNumArgs = 0) = BadRegisterSet ifTrue:
  		[objectRepresentation
  			genGetClassObjectOf: ReceiverResultReg
  			into: ClassReg
  			scratchReg: TempReg
  			instRegIsReceiver: methodOrBlockNumArgs = 0.
  		 self MoveR: ClassReg R: ReceiverResultReg].
+ 	self RetN: (self primRetNOffsetFor: 0).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveDiv (in category 'primitive generators') -----
  genPrimitiveDiv
  	| jumpNotSI jumpZero jumpExact jumpSameSign convert |
  	<var: #convert type: #'AbstractInstruction *'>
  	<var: #jumpZero type: #'AbstractInstruction *'>
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpExact type: #'AbstractInstruction *'>
  	<var: #jumpSameSign type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	self MoveR: TempReg R: Arg1Reg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	"We must shift away the tags, not just subtract them, so that the
  	 overflow case doesn't actually overflow the machine instruction."
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: ClassReg.
  	(self lastOpcode setsConditionCodesFor: JumpZero) ifFalse:
  		[self CmpCq: 0 R: ClassReg].
  	jumpZero := self JumpZero: 0.
  	self MoveR: ReceiverResultReg R: TempReg.
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: TempReg.
  	self DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg.
  	"If remainder is zero we must check for overflow."
  	self CmpCq: 0 R: ClassReg.
  	jumpExact := self JumpZero: 0.
  	"If arg and remainder signs are different we must round down."
  	self XorR: ClassReg R: Arg1Reg.
  	(self lastOpcode setsConditionCodesFor: JumpZero) ifFalse:
  		[self CmpCq: 0 R: Arg1Reg].
  	jumpSameSign := self JumpGreaterOrEqual: 0.
  	self SubCq: 1 R: TempReg.
  	jumpSameSign jmpTarget: (convert := self Label).
  	objectRepresentation genConvertIntegerToSmallIntegerInReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	"test for overflow; the only case is SmallInteger minVal // -1"
  	jumpExact jmpTarget:
  		(self CmpCq: (1 << (objectRepresentation numSmallIntegerBits - 1)) R: TempReg).
  	self JumpLess: convert.
  	jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveDivide (in category 'primitive generators') -----
  genPrimitiveDivide
  	| jumpNotSI jumpZero jumpInexact jumpOverflow |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpZero type: #'AbstractInstruction *'>
  	<var: #jumpInexact type: #'AbstractInstruction *'>
  	<var: #jumpOverflow type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	"We must shift away the tags, not just subtract them, so that the
  	 overflow case doesn't actually overflow the machine instruction."
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: ClassReg.
  	jumpZero := self JumpZero: 0.
  	self MoveR: ReceiverResultReg R: TempReg.
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: TempReg.
  	self DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg.
  	"If remainder is non-zero fail."
  	self CmpCq: 0 R: ClassReg.
  	jumpInexact := self JumpNonZero: 0.
  	"test for overflow; the only case is SmallInteger minVal / -1"
  	self CmpCq: (1 << (objectRepresentation numSmallIntegerBits - 1)) R: TempReg.
  	jumpOverflow := self JumpGreaterOrEqual: 0.
  	objectRepresentation genConvertIntegerToSmallIntegerInReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpOverflow jmpTarget: (jumpInexact jmpTarget: (jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label))).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveFloatSquareRoot (in category 'primitive generators') -----
  genPrimitiveFloatSquareRoot
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		return address"
  	| jumpFailAlloc |
  	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	self SqrtRd: DPFPReg0.
  	jumpFailAlloc := objectRepresentation
  					genAllocFloatValue: DPFPReg0
  					into: SendNumArgsReg
  					scratchReg: ClassReg
  					scratchReg: TempReg.
  	self MoveR: SendNumArgsReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 0).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize.
  	jumpFailAlloc jmpTarget: self Label.
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveIdentical (in category 'primitive generators') -----
  genPrimitiveIdentical
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
+ 	self genLoadArgAtDepth: 0 into: Arg0Reg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	^objectRepresentation
+ 		genInnerPrimitiveIdentical: (self primRetNOffsetFor: 1)
- 		genInnerPrimitiveIdentical: objectMemory wordSize * 2
  		orNotIf: false!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveIdentityHash (in category 'primitive generators') -----
  genPrimitiveIdentityHash
  	| r |
+ 	(r := objectRepresentation genInnerPrimitiveIdentityHash: (self primRetNOffsetFor: 0)) < 0 ifTrue:
- 	(r := objectRepresentation genInnerPrimitiveIdentityHash: objectMemory wordSize) < 0 ifTrue:
  		[^r].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveMod (in category 'primitive generators') -----
  genPrimitiveMod
  	| jumpNotSI jumpZero jumpExact jumpSameSign |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpZero type: #'AbstractInstruction *'>
  	<var: #jumpExact type: #'AbstractInstruction *'>
  	<var: #jumpSameSign type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ClassReg.
  	jumpZero := self JumpZero: 0.
  	self MoveR: ClassReg R: Arg1Reg.
  	self MoveR: ReceiverResultReg R: TempReg.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: TempReg.
  	self DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg.
  	"If remainder is zero we're done."
  	self CmpCq: 0 R: ClassReg.
  	jumpExact := self JumpZero: 0.
  	"If arg and remainder signs are different we must reflect around zero."
  	self XorR: ClassReg R: Arg1Reg.
  	(self lastOpcode setsConditionCodesFor: JumpZero) ifFalse:
  		[self CmpCq: 0 R: Arg1Reg].
  	jumpSameSign := self JumpGreaterOrEqual: 0.
  	self XorR: ClassReg R: Arg1Reg.
  	self AddR: Arg1Reg R: ClassReg.
  	jumpSameSign jmpTarget: (jumpExact jmpTarget: self Label).
  	objectRepresentation genSetSmallIntegerTagsIn: ClassReg.
  	self MoveR: ClassReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveMultiply (in category 'primitive generators') -----
  genPrimitiveMultiply
  	| jumpNotSI jumpOvfl |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpOvfl type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: ClassReg.
  	self MoveR: ReceiverResultReg R: TempReg.
  	objectRepresentation genRemoveSmallIntegerTagsInScratchReg: TempReg.
  	self MulR: TempReg R: ClassReg.
  	jumpOvfl := self JumpOverflow: 0.
  	objectRepresentation genSetSmallIntegerTagsIn: ClassReg.
  	self MoveR: ClassReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpOvfl jmpTarget: (jumpNotSI jmpTarget: self Label).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveNew (in category 'primitive generators') -----
  genPrimitiveNew
  	| r |
+ 	((r := objectRepresentation genInnerPrimitiveNew: (self primRetNOffsetFor: 0)) < 0
- 	((r := objectRepresentation genInnerPrimitiveNew: objectMemory wordSize) < 0
  	 and: [r ~= UnimplementedPrimitive]) ifTrue:
  		[^r].
  	"Call the interpreter primitive either when the machine-code primitive
  	 fails, or if the machine-code primitive is unimplemented."
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveNewMethod (in category 'primitive generators') -----
  genPrimitiveNewMethod
  	| r |
+ 	((r := objectRepresentation genInnerPrimitiveNewMethod: (self primRetNOffsetFor: 2)) < 0
- 	((r := objectRepresentation genInnerPrimitiveNewMethod: 2 * objectMemory wordSize) < 0
  	 and: [r ~= UnimplementedPrimitive]) ifTrue:
  		[^r].
  	"Call the interpreter primitive either when the machine-code primitive
  	 fails, or if the machine-code primitive is unimplemented."
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveNewWithArg (in category 'primitive generators') -----
  genPrimitiveNewWithArg
  	| r |
+ 	((r := objectRepresentation genInnerPrimitiveNewWithArg: (self primRetNOffsetFor: 1)) < 0
- 	((r := objectRepresentation genInnerPrimitiveNewWithArg: objectMemory wordSize) < 0
  	 and: [r ~= UnimplementedPrimitive]) ifTrue:
  		[^r].
  	"Call the interpreter primitive either when the machine-code primitive
  	 fails, or if the machine-code primitive is unimplemented."
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveNotIdentical (in category 'primitive generators') -----
  genPrimitiveNotIdentical
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
+ 	self genLoadArgAtDepth: 0 into: Arg0Reg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	^objectRepresentation
+ 		genInnerPrimitiveIdentical: (self primRetNOffsetFor: 1)
- 		genInnerPrimitiveIdentical: objectMemory wordSize * 2
  		orNotIf: true!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveQuo (in category 'primitive generators') -----
  genPrimitiveQuo
  	| jumpNotSI jumpZero jumpOverflow |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpZero type: #'AbstractInstruction *'>
  	<var: #jumpOverflow type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	"We must shift away the tags, not just subtract them, so that the
  	 overflow case doesn't actually overflow the machine instruction."
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: ClassReg.
  	(self lastOpcode setsConditionCodesFor: JumpZero) ifFalse:
  		[self CmpCq: 0 R: ClassReg].
  	jumpZero := self JumpZero: 0.
  	self MoveR: ReceiverResultReg R: TempReg.
  	objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: TempReg.
  	self DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg.
  	"test for overflow; the only case is SmallInteger minVal quo: -1"
  	self CmpCq: (1 << (objectRepresentation numSmallIntegerBits - 1)) R: TempReg.
  	jumpOverflow := self JumpGreaterOrEqual: 0.
  	objectRepresentation genConvertIntegerToSmallIntegerInReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpOverflow jmpTarget: (jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label)).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveSize (in category 'primitive generators') -----
  genPrimitiveSize
  	| r |
+ 	(r := objectRepresentation genInnerPrimitiveSize: (self primRetNOffsetFor: 0)) < 0 ifTrue:
- 	(r := objectRepresentation genInnerPrimitiveSize: objectMemory wordSize) < 0 ifTrue:
  		[^r].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveStringAt (in category 'primitive generators') -----
  genPrimitiveStringAt
  	| r |
+ 	self genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	(r := objectRepresentation genInnerPrimitiveStringAt: (self primRetNOffsetFor: 1)) < 0 ifTrue:
- 	self MoveMw: objectMemory wordSize r: SPReg R: Arg0Reg.
- 	(r := objectRepresentation genInnerPrimitiveStringAt: objectMemory wordSize * 2) < 0 ifTrue:
  		[^r].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveStringAtPut (in category 'primitive generators') -----
  genPrimitiveStringAtPut
  	| r |
+ 	self genLoadArgAtDepth: 1 into: Arg0Reg.
+ 	self genLoadArgAtDepth: 0 into: Arg1Reg.
+ 	((r := objectRepresentation genInnerPrimitiveStringAtPut: (self primRetNOffsetFor: 2)) < 0
- 	self MoveMw: objectMemory wordSize * 2 r: SPReg R: Arg0Reg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: Arg1Reg.
- 	((r := objectRepresentation genInnerPrimitiveStringAtPut: objectMemory wordSize * 3) < 0
  	 and: [r ~= UnimplementedPrimitive]) ifTrue:
  		[^r].
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveSubtract (in category 'primitive generators') -----
  genPrimitiveSubtract
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
  	| jumpNotSI jumpOvfl |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpOvfl type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	self MoveR: ReceiverResultReg R: TempReg.
  	self SubR: ClassReg R: TempReg.
  	jumpOvfl := self JumpOverflow: 0.
  	objectRepresentation genAddSmallIntegerTagsTo: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpOvfl jmpTarget: (jumpNotSI jmpTarget: self Label).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genReturnNilFromBlock (in category 'bytecode generators') -----
  genReturnNilFromBlock
  	self assert: inBlock.
- 	self flag: 'currently caller pushes result'.
  	self genMoveConstant: objectMemory nilObject R: ReceiverResultReg.
  	^self genBlockReturn!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genReturnReceiver (in category 'bytecode generators') -----
  genReturnReceiver
  	"Frameless method activation looks like
  				receiver
  				args
  		sp->	ret pc.
  	 Return pops receiver and arguments off the stack.  Callee pushes the result."
- 	self flag: 'currently caller pushes result'.
  	needsFrame ifTrue:
  		[self MoveMw: FoxMFReceiver r: FPReg R: ReceiverResultReg].
  	^self genUpArrowReturn!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genReturnTopFromBlock (in category 'bytecode generators') -----
  genReturnTopFromBlock
  	self assert: inBlock.
- 	self flag: 'currently caller pushes result'.
  	self PopR: ReceiverResultReg.
  	^self genBlockReturn!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genReturnTopFromMethod (in category 'bytecode generators') -----
  genReturnTopFromMethod
  	"Return pops receiver and arguments off the stack.  Callee pushes the result."
- 	self flag: 'currently caller pushes result'.
  	self PopR: ReceiverResultReg.
  	^self genUpArrowReturn!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSend:numArgs:sendTable: (in category 'bytecode generator support') -----
  genSend: selector numArgs: numArgs sendTable: sendTable
  	<inline: false>
  	<var: #sendTable type: #'sqInt *'>
  	| annotation |
  	(objectMemory isYoung: selector) ifTrue:
  		[hasYoungReferent := true].
  	self assert: needsFrame.
  	annotation := self annotationForSendTable: sendTable.
  	self assert: (numArgs between: 0 and: 255). "say"
  	self assert: (objectMemory addressCouldBeOop: selector).
  	self MoveMw: numArgs * objectMemory wordSize r: SPReg R: ReceiverResultReg.
  	"Deal with stale super sends; see SpurMemoryManager's class comment."
  	(self annotationIsForUncheckedEntryPoint: annotation) ifTrue:
  		[objectRepresentation genEnsureOopInRegNotForwarded: ReceiverResultReg scratchReg: TempReg].
  	numArgs > 2 ifTrue:
  		[self MoveCq: numArgs R: SendNumArgsReg].
  	(BytecodeSetHasDirectedSuperSend
  	 and: [annotation = IsDirectedSuperSend]) ifTrue:
  		[self genMoveConstant: tempOop R: TempReg].
  	self MoveCw: selector R: ClassReg.
  	self annotate: (self Call: (sendTable at: (numArgs min: NumSendTrampolines - 1)))
  		with: annotation.
- 	self flag: 'currently caller pushes result'.
  	self PushR: ReceiverResultReg.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSmallIntegerComparison: (in category 'primitive generators') -----
  genSmallIntegerComparison: jumpOpcode
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
  	| jumpFail jumpTrue |
  	<var: #jumpFail type: #'AbstractInstruction *'>
  	<var: #jumpTrue type: #'AbstractInstruction *'>
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpFail := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	self CmpR: ClassReg R: ReceiverResultReg. "N.B. FLAGS := RRReg - ClassReg"
  	jumpTrue := self gen: jumpOpcode.
  	self genMoveFalseR: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpTrue jmpTarget: (self genMoveTrueR: ReceiverResultReg).
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self RetN: objectMemory wordSize * 2.
  	jumpFail jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSmallIntegerComparison:orDoubleComparison: (in category 'primitive generators') -----
  genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator
  	"Stack looks like
  		receiver (also in ResultReceiverReg)
  		arg
  		return address"
  	| jumpDouble jumpNonInt jumpFail jumpTrue jumpCond |
  	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
  	<var: #jumpDouble type: #'AbstractInstruction *'>
  	<var: #jumpNonInt type: #'AbstractInstruction *'>
  	<var: #jumpCond type: #'AbstractInstruction *'>
  	<var: #jumpTrue type: #'AbstractInstruction *'>
  	<var: #jumpFail type: #'AbstractInstruction *'>
  	backEnd hasDoublePrecisionFloatingPointSupport ifFalse:
  		[^self genSmallIntegerComparison: jumpOpcode].
+ 	self genLoadArgAtDepth: 0 into: TempReg.
- 	self MoveMw: objectMemory wordSize r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpDouble := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	self CmpR: ClassReg R: ReceiverResultReg. "N.B. FLAGS := RRReg - ClassReg"
  	jumpTrue := self gen: jumpOpcode.
  	self genMoveFalseR: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpTrue jmpTarget: (self genMoveTrueR: ReceiverResultReg).
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self RetN: objectMemory wordSize * 2.
  	
  	"Argument may be a Float : let us check or fail"
  	jumpDouble jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[self MoveR: ClassReg R: TempReg.
  		 jumpNonInt := objectRepresentation genJumpImmediateInScratchReg: TempReg].
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: SendNumArgsReg.
  	objectRepresentation genCmpClassFloatCompactIndexR: SendNumArgsReg.
  	jumpFail := self JumpNonZero: 0.
  
  	"It was a Float, so convert the receiver to double and perform the operation"
  	self MoveR: ReceiverResultReg R: TempReg.
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: TempReg.
  	self ConvertR: TempReg Rd: DPFPReg0.
  	objectRepresentation genGetDoubleValueOf: ClassReg into: DPFPReg1.
  	self CmpRd: DPFPReg1 Rd: DPFPReg0.
  	jumpCond := self perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
  	self genMoveFalseR: ReceiverResultReg.
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self flag: 'currently caller pushes result'.
- 	self RetN: objectMemory wordSize * 2.
  	jumpCond jmpTarget: (self genMoveTrueR: ReceiverResultReg).
+ 	self RetN: (self primRetNOffsetFor: 1).
- 	self RetN: objectMemory wordSize * 2.
  
  	objectRepresentation smallIntegerIsOnlyImmediateType
  		ifTrue: [jumpFail jmpTarget: self Label]
  		ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: self Label)].
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genSpecialSelectorEqualsEquals (in category 'bytecode generators') -----
  genSpecialSelectorEqualsEquals
  	| jumpNotEqual jumpPush |
  	<var: #jumpNotEqual type: #'AbstractInstruction *'>
  	<var: #jumpPush type: #'AbstractInstruction *'>
  	self PopR: Arg0Reg.
  	objectRepresentation
+ 		genEnsureOopInRegNotForwarded: Arg0Reg
- 		genEnsureObjInRegNotForwarded: Arg0Reg
  		scratchReg: TempReg.
  	self MoveMw: 0 r: SPReg R: ClassReg.
  	objectRepresentation
+ 		genEnsureOopInRegNotForwarded: ClassReg
- 		genEnsureObjInRegNotForwarded: ClassReg
  		scratchReg: TempReg.
  	self CmpR: Arg0Reg R: ClassReg.
  	jumpNotEqual := self JumpNonZero: 0.
  	self annotate: (self genMoveTrueR: Arg0Reg)
  		objRef: objectMemory trueObject.
  	jumpPush := self Jump: 0.
  	jumpNotEqual jmpTarget: (self genMoveFalseR: Arg0Reg).
  	jumpPush jmpTarget: (self MoveR: Arg0Reg Mw: 0 r: SPReg).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genUpArrowReturn (in category 'bytecode generators') -----
  genUpArrowReturn
  	"Generate a method return from within a method or a block.
  	 Frameless method activation looks like
  				receiver
  				args
  		sp->	ret pc.
  	 Return pops receiver and arguments off the stack.  Callee pushes the result."
- 	self flag: 'currently caller pushes result'.
  	inBlock ifTrue:
  		[self assert: needsFrame.
  		 self annotateBytecode: (self CallRT: ceNonLocalReturnTrampoline).
  		 ^0].
  	needsFrame ifTrue:
  		[self MoveR: FPReg R: SPReg.
  		 self PopR: FPReg.
  		 backEnd hasLinkRegister ifTrue:
  			[self PopR: LinkReg]].
  	self RetN: methodOrBlockNumArgs + 1 * objectMemory wordSize.
  	^0!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>primRetNOffsetFor: (in category 'primitive generators') -----
+ primRetNOffsetFor: nargs
+ 	"Answer how many bytes to cut back the stack to remove the receiver
+ 	 and arguments after an invocation of a primitive with nargs arguments. "
+ 	^nargs + 1 * objectMemory wordSize!

Item was added:
+ ----- Method: SimpleStackBasedCogit>>register:isInMask: (in category 'simulation stack') -----
+ register: reg isInMask: mask
+ 	<inline: true>
+ 	^ mask anyMask: (self registerMaskFor: reg)!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>returnRegForStoreCheck (in category 'trampolines') -----
  returnRegForStoreCheck
+ 	"We must ensure the ReceiverResultReg is live across the store check so that
+ 	 we can store into receiver inst vars in a frameless method since self exists
+ 	 only in ReceiverResultReg in a frameless method.  So if ReceiverResultReg is
+ 	 caller-saved we use the fact that ceStoreCheck: answers its argument to
+ 	 reload ReceiverResultReg cheaply.  Otherwise we don't care about the result
+ 	 and use the cResultRegister, effectively a no-op (see compileTrampoline...)"
+ 
+ 	^(self register: ReceiverResultReg isInMask: callerSavedRegMask)
+ 		ifTrue: [ReceiverResultReg]
+ 		ifFalse: [backEnd cResultRegister]!
- 	"See the subclass for explanation."
- 	^backEnd cResultRegister!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>genLoadArgAtDepth:into: (in category 'primitive generators') -----
+ genLoadArgAtDepth: n into: reg
+ 	self shouldNotImplement!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>primRetNOffsetFor: (in category 'primitive generators') -----
+ primRetNOffsetFor: nargs
+ 	self shouldNotImplement!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>register:isInMask: (in category 'simulation stack') -----
- register: reg isInMask: mask
- 	<inline: true>
- 	^ mask anyMask: (self registerMaskFor: reg)!

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>returnRegForStoreCheck (in category 'trampolines') -----
- returnRegForStoreCheck
- 	"We must ensure the ReceiverResultReg is live across the store check so that
- 	 we can store into receiver inst vars in a frameless method since self exists
- 	 only in ReceiverResultReg in a frameless method.  So if ReceiverResultReg is
- 	 caller-saved we use the fact that ceStoreCheck: answers its argument to
- 	 reload ReceiverResultReg cheaply.  Otherwise we don't care about the result
- 	 and use the cResultRegister, effectively a no-op (see compileTrampoline...)"
- 
- 	^(self register: ReceiverResultReg isInMask: callerSavedRegMask)
- 		ifTrue: [ReceiverResultReg]
- 		ifFalse: [backEnd cResultRegister]!



More information about the Vm-dev mailing list