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

commits at source.squeak.org commits at source.squeak.org
Fri Dec 6 22:58:13 UTC 2013


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

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

Name: VMMaker.oscog-eem.546
Author: eem
Time: 6 December 2013, 2:53:39.599 pm
UUID: d745c2ec-3cc8-4612-9ff5-0c85fe771ced
Ancestors: VMMaker.oscog-eem.545

Rename the three genConvertFooToBarInScratchReg:'s to
genConvertFooToBarInReg:

=============== Diff against VMMaker.oscog-eem.545 ===============

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genConvertIntegerToSmallIntegerInReg: (in category 'compile abstract instructions') -----
+ genConvertIntegerToSmallIntegerInReg: reg
+ 	cogit LogicalShiftLeftCq: 1 R: reg.
+ 	cogit AddCq: 1 R: reg.
+ 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genConvertSmallIntegerToIntegerInReg: (in category 'compile abstract instructions') -----
+ genConvertSmallIntegerToIntegerInReg: reg
+ 	cogit ArithmeticShiftRightCq: 1 R: reg.
+ 	^0!

Item was removed:
- ----- Method: CogObjectRepresentationFor32BitSpur>>genConvertSmallIntegerToIntegerInScratchReg: (in category 'compile abstract instructions') -----
- genConvertSmallIntegerToIntegerInScratchReg: scratchReg
- 	cogit ArithmeticShiftRightCq: 1 R: scratchReg.
- 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genGetHashFieldNonImmOf:asSmallIntegerInto: (in category 'compile abstract instructions') -----
  genGetHashFieldNonImmOf: instReg asSmallIntegerInto: destReg
  	"Fetch the instance's identity hash into destReg, encoded as a SmallInteger."
  	"Get header word in scratchReg"
  	cogit MoveMw: 4 r: instReg R: destReg.
  	"Shift and mask the field leaving room for the SmallInteger tag."
  	cogit AndCq: objectMemory identityHashHalfWordMask R: destReg.
+ 	self genConvertIntegerToSmallIntegerInReg: destReg.
- 	self genConvertIntegerToSmallIntegerInScratchReg: destReg.
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: (in category 'primitive generators') -----
  genGetSizeOf: sourceReg into: destReg formatReg: formatReg scratchReg: scratchReg abortJumpsInto: aBinaryBlock
  	"Get the size of the non-immediate object in sourceReg into destReg using formatReg
  	 and scratchReg as temps.  None of these registers can overlap.  Supply the jumps
  	 taken if the object in sourceReg is not indexable, or if the object in sourceReg is a
  	 context.. Hack: If the object has a pointer format other than 2 leave the number of
  	 fixed fields in formatReg.  Used by primitiveSize, primitiveAt, and primitiveAtPut"
  	<returnTypeC: #'AbstractInstruction *'>
  	| jumpNotIndexable jumpSmallSize
  	  jumpBytesDone jumpShortsDone jumpArrayDone jump32BitLongsDone
  	  jumpIsBytes jumpHasFixedFields jumpIsShorts jumpIsContext  |
  	<inline: true>
  	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  	<var: #jumpIsBytes type: #'AbstractInstruction *'>
  	<var: #jumpIsShorts type: #'AbstractInstruction *'>
  	<var: #jumpSmallSize type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpArrayDone type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  	<var: #jump32BitLongsDone type: #'AbstractInstruction *'>
  
  	cogit
  		MoveMw: 0 r: sourceReg R: formatReg;				"formatReg := least significant half of self baseHeader: receiver"
  		MoveR: formatReg R: scratchReg;
  		LogicalShiftRightCq: objectMemory formatShift R: formatReg;
  		AndCq: objectMemory formatMask R: formatReg.	"formatReg := self formatOfHeader: destReg"
  
  	"get numSlots into destReg."
  	cogit MoveCq: 0 R: destReg. "N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: 7 r: sourceReg R: destReg. "MSB of header"
  	cogit CmpCq: objectMemory numSlotsMask R: destReg.
  	jumpSmallSize := cogit JumpLess: 0.
  	cogit MoveMw: -8 r: sourceReg R: destReg. "LSW of overflow size header"
  
  	"dispatch on format in a combination of highest dynamic frequency order first and convenience.
  		  0 = 0 sized objects (UndefinedObject True False et al)
  		  1 = non-indexable objects with inst vars (Point et al)
  		  2 = indexable objects with no inst vars (Array et al)
  		  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  		  4 = weak indexable objects with inst vars (WeakArray et al)
  		  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  		  6 unused, reserved for exotic pointer objects?
  		  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  		  8 unused, reserved for exotic non-pointer objects?
  		  9 (?) 64-bit indexable
  		10 - 11 32-bit indexable
  		12 - 15 16-bit indexable
  		16 - 23 byte indexable
  		24 - 31 compiled method"
  	jumpSmallSize jmpTarget:
  					(cogit CmpCq: objectMemory firstByteFormat R: formatReg).
  	jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory arrayFormat R: formatReg.
  	jumpArrayDone := cogit JumpZero: 0.
  	jumpNotIndexable := cogit JumpLess: 0.
  					cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  	jumpHasFixedFields := cogit JumpLessOrEqual: 0.
  					cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  	jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  	jump32BitLongsDone := cogit JumpGreaterOrEqual: 0.
  	"For now ignore 64-bit indexability."
  	jumpNotIndexable jmpTarget: cogit Label.
  	jumpNotIndexable := cogit Jump: 0.
  
  	jumpIsBytes jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: destReg).
  		cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  		cogit SubR: formatReg R: destReg.
  	jumpBytesDone := cogit Jump: 0.
  
  	jumpIsShorts jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: destReg).
  		cogit AndCq: 1 R: formatReg.
  		cogit SubR: formatReg R: destReg.
  	jumpShortsDone := cogit Jump: 0.
  
  	"formatReg contains fmt, now up for grabs.
  	 destReg contains numSlots, precious.
  	 sourceReg must be preserved"
  	jumpHasFixedFields jmpTarget:
  		(cogit AndCq: objectMemory classIndexMask R: scratchReg).
  	cogit MoveR: scratchReg R: formatReg.
  	cogit CmpCq: ClassMethodContextCompactIndex R: scratchReg.
  	jumpIsContext := cogit JumpZero: 0.
  	cogit PushR: destReg.
  	self genGetClassObjectOfClassIndex: formatReg into: destReg scratchReg: scratchReg.
  	self genLoadSlot: InstanceSpecificationIndex sourceReg: destReg destReg: formatReg.
+ 	self genConvertSmallIntegerToIntegerInReg: formatReg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: formatReg.
  	cogit
  		PopR: destReg;
  		AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  		SubR: formatReg R: destReg.
  
  	jumpArrayDone jmpTarget:
  	(jump32BitLongsDone jmpTarget:
  	(jumpShortsDone jmpTarget:
  	(jumpBytesDone jmpTarget:
  		cogit Label))).
  	aBinaryBlock value: jumpNotIndexable value: jumpIsContext!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  	"Implement the guts of primitiveAt; dispatch on size"
  	| formatReg jumpNotIndexable jumpSmallSize jumpImmediate jumpBadIndex
  	  jumpBytesDone jumpShortsDone jumpWordsDone jumpFixedFieldsDone
  	  jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig jumpIsArray jumpHasFixedFields jumpIsContext
  	  jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds jumpArrayOutOfBounds jumpFixedFieldsOutOfBounds |
  	<inline: true>
  	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  	<var: #jumpIsBytes type: #'AbstractInstruction *'>
  	<var: #jumpIsShorts type: #'AbstractInstruction *'>
  	<var: #jumpBadIndex type: #'AbstractInstruction *'>
  	<var: #jumpSmallSize type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpBytesDone type: #'AbstractInstruction *'>
  	<var: #jumpShortsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordsDone type: #'AbstractInstruction *'>
  	<var: #jumpWordTooBig type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpHasFixedFields type: #'AbstractInstruction *'>
  	<var: #jumpFixedFieldsDone type: #'AbstractInstruction *'>
  	<var: #jumpArrayOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpFixedFieldsOutOfBounds type: #'AbstractInstruction *'>
  
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpImmediate := self genJumpImmediateInScratchReg: TempReg.
  	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
  	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
+ 	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
  
  	formatReg := SendNumArgsReg.
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: formatReg;		"formatReg := least significant half of self baseHeader: receiver"
  		MoveR: formatReg R: TempReg;
  		LogicalShiftRightCq: objectMemory formatShift R: formatReg;
  		AndCq: objectMemory formatMask R: formatReg.	"formatReg := self formatOfHeader: destReg"
  
  	"get numSlots into ClassReg."
  	cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
  	cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
  	jumpSmallSize := cogit JumpLess: 0.
  	cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
  
  	"dispatch on format in a combination of highest dynamic frequency order first and convenience.
  		  0 = 0 sized objects (UndefinedObject True False et al)
  		  1 = non-indexable objects with inst vars (Point et al)
  		  2 = indexable objects with no inst vars (Array et al)
  		  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  		  4 = weak indexable objects with inst vars (WeakArray et al)
  		  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  		  6 unused, reserved for exotic pointer objects?
  		  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  		  8 unused, reserved for exotic non-pointer objects?
  		  9 (?) 64-bit indexable
  		10 - 11 32-bit indexable
  		12 - 15 16-bit indexable
  		16 - 23 byte indexable
  		24 - 31 compiled method"
  	jumpSmallSize jmpTarget:
  					(cogit CmpCq: objectMemory firstByteFormat R: formatReg).
  	jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory arrayFormat R: formatReg.
  	jumpIsArray := cogit JumpZero: 0.
  	jumpNotIndexable := cogit JumpLess: 0.
  					cogit CmpCq: objectMemory weakArrayFormat R: formatReg.
  	jumpHasFixedFields := cogit JumpLessOrEqual: 0.
  					cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  	jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  	jumpIsWords := cogit JumpGreaterOrEqual: 0.
  	"For now ignore 64-bit indexability."
  	jumpNotIndexable jmpTarget: cogit Label.
  	jumpNotIndexable := cogit Jump: 0.
  
  	jumpIsBytes jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  		cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  		cogit SubR: formatReg R: ClassReg;
  		CmpR: Arg1Reg R: ClassReg.
  	jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  	cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
+ 	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
- 	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	jumpBytesDone := cogit Jump: 0.
  
  	jumpIsShorts jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  		cogit AndCq: 1 R: formatReg.
  		cogit SubR: formatReg R: ClassReg;
  		CmpR: Arg1Reg R: ClassReg.
  	jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddR: Arg1Reg R: ReceiverResultReg.
  	cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	jumpShortsDone := cogit Jump: 0.
  
  	jumpIsWords jmpTarget:
  		(cogit CmpR: Arg1Reg R: ClassReg).
  	jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  	cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
  	cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  	jumpWordTooBig := self jumpNotSmallIntegerUnsignedValueInRegister: TempReg.
  	cogit MoveR: TempReg R: ReceiverResultReg.
  	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	jumpWordsDone := cogit Jump: 0.
  
  	jumpHasFixedFields jmpTarget:
  		(cogit AndCq: objectMemory classIndexMask R: TempReg).
  	cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  	cogit MoveR: TempReg R: formatReg.
  	cogit CmpCq: ClassMethodContextCompactIndex R: TempReg.
  	jumpIsContext := cogit JumpZero: 0.
  	cogit PushR: ClassReg.
  	self genGetClassObjectOfClassIndex: formatReg into: ClassReg scratchReg: TempReg.
  	self genLoadSlot: InstanceSpecificationIndex sourceReg: ClassReg destReg: formatReg.
  	cogit PopR: ClassReg.
+ 	self genConvertSmallIntegerToIntegerInReg: formatReg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: formatReg.
  	cogit
  		AndCq: objectMemory fixedFieldsOfClassFormatMask R: formatReg;
  		SubR: formatReg R: ClassReg;
  		CmpR: Arg1Reg R: ClassReg.
  	jumpFixedFieldsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	"index is (formatReg (fixed fields) + Arg1Reg (0-rel index)) * wordSize + baseHeaderSize"
  	cogit AddR: formatReg R: Arg1Reg.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  	cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  	jumpFixedFieldsDone := cogit Jump: 0.
  
  	jumpIsArray jmpTarget:
  		(cogit CmpR: Arg1Reg R: ClassReg).
  	jumpArrayOutOfBounds := cogit JumpBelowOrEqual: 0.	
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  	cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  
  	jumpFixedFieldsDone jmpTarget:
  	(jumpWordsDone jmpTarget:
  	(jumpShortsDone jmpTarget:
  	(jumpBytesDone jmpTarget:
  		(cogit RetN: retNoffset)))).
  
  	jumpFixedFieldsOutOfBounds jmpTarget:
  	(jumpArrayOutOfBounds jmpTarget:
  	(jumpBytesOutOfBounds jmpTarget:
  	(jumpShortsOutOfBounds jmpTarget:
  	(jumpWordsOutOfBounds jmpTarget:
  	(jumpWordTooBig jmpTarget:
  	(jumpNotIndexable jmpTarget:
  	(jumpIsContext jmpTarget:
  	(jumpBadIndex jmpTarget:
  	(jumpImmediate jmpTarget: cogit Label))))))))).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveNew: (in category 'primitive generators') -----
  genInnerPrimitiveNew: retNoffset
  	"Implement primitiveNew for convenient cases:
  	- the receiver has a hash
  	- the receiver is fixed size (excluding ephemerons to save instructions & miniscule time)
  	- single word header/num slots < numSlotsMask
  	- the result fits in eden (actually below scavengeThreshold)"
  
  	| halfHeaderReg fillReg instSpecReg byteSizeReg
  	  jumpUnhashed jumpVariableOrEphemeron jumpNoSpace jumpTooBig jumpHasSlots
  	  fillLoop skip |
  	<var: 'skip' type: #'AbstractInstruction *'>
  	<var: 'fillLoop' type: #'AbstractInstruction *'>
  	<var: 'jumpTooBig' type: #'AbstractInstruction *'>
  	<var: 'jumpHasSlots' type: #'AbstractInstruction *'>
  	<var: 'jumpNoSpace' type: #'AbstractInstruction *'>
  	<var: 'jumpUnhashed' type: #'AbstractInstruction *'>
  	<var: 'jumpVariableOrEphemeron' type: #'AbstractInstruction *'>
  
  	"half header will contain 1st half of header (classIndex/class's hash & format),
  	 then 2nd half of header (numSlots/fixed size) and finally fill value (nilObject)."
  	halfHeaderReg := fillReg := SendNumArgsReg.
  	"inst spec will hold class's instance specification, then byte size and finally end of new object."
  	instSpecReg := byteSizeReg := ClassReg.
  
  	"get freeStart as early as possible so as not to wait later..."
  	cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
  	"get class's hash & fail if 0"
  	self genGetHashFieldNonImmOf: ReceiverResultReg into: halfHeaderReg.
  	jumpUnhashed := cogit JumpZero: 0.
  	"get class's format inst var for both inst spec (format field) and num fixed fields"
  	self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: TempReg.
+ 	self genConvertSmallIntegerToIntegerInReg: TempReg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: TempReg.
  	cogit MoveR: TempReg R: instSpecReg.
  	cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth R: TempReg.
  	cogit AndCq: objectMemory formatMask R: TempReg.
  	cogit AndCq: objectMemory fixedFieldsOfClassFormatMask R: instSpecReg.
  	"fail if not fixed or if ephemeron (rare beasts so save the cycles)"
  	cogit CmpCq: objectMemory nonIndexablePointerFormat R: TempReg.
  	jumpVariableOrEphemeron := cogit JumpAbove: 0.
  	cogit CmpCq: objectMemory numSlotsMask R: instSpecReg.
  	jumpTooBig := cogit JumpAboveOrEqual: 0.
  	"Add format to classIndex/format half header; other word contains numSlots"
  	cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  	cogit AddR: TempReg R: halfHeaderReg.
  	"write half header now; it frees halfHeaderReg"
  	cogit MoveR: halfHeaderReg Mw: 0 r: Arg1Reg.
  	"save unrounded numSlots for header"
  	cogit MoveR: instSpecReg R: halfHeaderReg.
  	"compute byte size; remember 0-sized objects still need 1 slot & allocation is
  	 rounded up to 8 bytes."
  	cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"
  	jumpHasSlots := cogit JumpNonZero: 0.
  	cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.
  	skip := cogit Jump: 0.
  	"round up to allocationUnit"
  	jumpHasSlots jmpTarget:
  	(cogit MoveR: byteSizeReg R: TempReg).
  	cogit AndCq: 1 R: TempReg.
  	cogit AddR: TempReg R: byteSizeReg.
  	cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.
  	skip jmpTarget:
  	"shift halfHeaderReg to put numSlots in correct place"
  	(cogit LogicalShiftLeftCq: objectMemory numSlotsHalfShift R: halfHeaderReg).
  	"check if allocation fits (freeSize + byteSize < scavengeThreshold); scavengeThreshold is constant."
  	cogit AddR: Arg1Reg R: byteSizeReg.
  	cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
  	jumpNoSpace := cogit JumpAboveOrEqual: 0.
  	"write back new freeStart; get result. byteSizeReg holds new freeStart, the limit of the object"
  	cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	"write other half of header (numSlots/identityHash)"
  	cogit MoveR: halfHeaderReg Mw: 4 r: Arg1Reg.
  	"now fill"
  	cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
  	cogit MoveCq: objectMemory nilObject R: fillReg.
  	"at least two words; so can make this a [fill 2 words. reached limit?] whileFalse"
  	fillLoop := 
  	cogit MoveR: fillReg Mw: 0 r: Arg1Reg.
  	cogit MoveR: fillReg Mw: 4 r: Arg1Reg.
  	cogit AddCq: 8 R: Arg1Reg.
  	cogit CmpR: Arg1Reg R: byteSizeReg.
  	cogit JumpAbove: fillLoop.
  	cogit RetN: retNoffset.
  
  	jumpUnhashed jmpTarget:
  	(jumpVariableOrEphemeron jmpTarget:
  	(jumpTooBig jmpTarget:
  	(jumpNoSpace jmpTarget: cogit Label))).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveNewWithArg: (in category 'primitive generators') -----
  genInnerPrimitiveNewWithArg: retNoffset
  	"Implement primitiveNewWithArg for convenient cases:
  	- the receiver has a hash
  	- the receiver is variable and not compiled method
  	- single word header/num slots < numSlotsMask
  	- the result fits in eden
  	See superclass method for dynamic frequencies of formats.
  	For the moment we implement only arrayFormat, firstByteFormat & firstLongFormat"
  
  	| halfHeaderReg fillReg instSpecReg byteSizeReg maxSlots
  	  jumpArrayTooBig jumpByteTooBig jumpLongTooBig
  	  jumpArrayFormat jumpByteFormat jumpBytePrepDone jumpLongPrepDone
  	  jumpUnhashed jumpNElementsNonInt jumpFailCuzFixed jumpNoSpace jumpHasSlots fillLoop skip |
  	<var: 'skip' type: #'AbstractInstruction *'>
  	<var: 'fillLoop' type: #'AbstractInstruction *'>	
  	<var: 'jumpHasSlots' type: #'AbstractInstruction *'>
  	<var: 'jumpNoSpace' type: #'AbstractInstruction *'>
  	<var: 'jumpUnhashed' type: #'AbstractInstruction *'>
  	<var: 'jumpByteFormat' type: #'AbstractInstruction *'>
  	<var: 'jumpByteTooBig' type: #'AbstractInstruction *'>
  	<var: 'jumpLongTooBig' type: #'AbstractInstruction *'>
  	<var: 'jumpArrayFormat' type: #'AbstractInstruction *'>
  	<var: 'jumpArrayTooBig' type: #'AbstractInstruction *'>
  	<var: 'jumpFailCuzFixed' type: #'AbstractInstruction *'>
  	<var: 'jumpBytePrepDone' type: #'AbstractInstruction *'>
  	<var: 'jumpLongPrepDone' type: #'AbstractInstruction *'>
  	<var: 'jumpNElementsNonInt' type: #'AbstractInstruction *'>
  
  	"half header will contain 1st half of header (classIndex/class's hash & format),
  	 then 2nd half of header (numSlots) and finally fill value (nilObject)."
  	halfHeaderReg := fillReg := SendNumArgsReg.
  	"inst spec will hold class's instance specification and then byte size and finally numSlots half of header"
  	instSpecReg := byteSizeReg := ClassReg.
  	"The max slots we'll allocate here are those for a single header"
  	maxSlots := objectMemory numSlotsMask - 1.
  
  	"get freeStart as early as possible so as not to wait later..."
  	cogit MoveAw: objectMemory freeStartAddress R: Arg1Reg.
  	"get class's hash & fail if 0"
  	self genGetHashFieldNonImmOf: ReceiverResultReg into: halfHeaderReg.
  	jumpUnhashed := cogit JumpZero: 0.
  	"get index and fail if not a +ve integer"
  	cogit MoveR: Arg0Reg R: TempReg.
  	jumpNElementsNonInt := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	"get class's format inst var for inst spec (format field)"
  	self genLoadSlot: InstanceSpecificationIndex sourceReg: ReceiverResultReg destReg: instSpecReg.
  	cogit LogicalShiftRightCq: objectMemory fixedFieldsFieldWidth + self numSmallIntegerTagBits R: instSpecReg.
  	cogit AndCq: objectMemory formatMask R: instSpecReg.
  	"Add format to classIndex/format half header now"
  	cogit MoveR: instSpecReg R: TempReg.
  	cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  	cogit AddR: TempReg R: halfHeaderReg.
  	"get integer value of num fields in TempReg now"
  	cogit MoveR: Arg0Reg R: TempReg.
+ 	self genConvertSmallIntegerToIntegerInReg: TempReg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: TempReg.
  	"dispatch on format, failing if not variable or if compiled method"
  	cogit CmpCq: objectMemory arrayFormat R: instSpecReg.
  	jumpArrayFormat := cogit JumpZero: 0.
  	cogit CmpCq: objectMemory firstByteFormat R: instSpecReg.
  	jumpByteFormat := cogit JumpZero: 0.
  	cogit CmpCq: objectMemory firstLongFormat R: instSpecReg.
  	jumpFailCuzFixed := cogit JumpNonZero: 0.
  
  	cogit CmpCq: (objectMemory integerObjectOf: maxSlots) R: Arg0Reg.
  	jumpLongTooBig := cogit JumpAbove: 0.
  	"save num elements/slot size to instSpecReg"
  	cogit MoveR: TempReg R: instSpecReg.
  	"push fill value"
  	cogit MoveCq: 0 R: TempReg.
  	cogit PushR: TempReg.
  	jumpLongPrepDone := cogit Jump: 0. "go allocate"
  
  	jumpByteFormat jmpTarget:
  	(cogit CmpCq: (objectMemory integerObjectOf: maxSlots * objectMemory wordSize) R: Arg0Reg).
  	jumpByteTooBig := cogit JumpAbove: 0.
  	"save num elements to instSpecReg"
  	cogit MoveR: TempReg R: instSpecReg.
  	"compute odd bits and add into halfHeaderReg; oddBits := 4 - nElements bitAnd: 3"
  	cogit MoveCq: objectMemory wordSize R: TempReg.
  	cogit SubR: instSpecReg R: TempReg.
  	cogit AndCq: objectMemory wordSize - 1 R: TempReg.
  	cogit LogicalShiftLeftCq: objectMemory formatShift R: TempReg.
  	cogit AddR: TempReg R: halfHeaderReg.
  	"round up num elements to numSlots in instSpecReg"
  	cogit AddCq: objectMemory wordSize - 1 R: instSpecReg.
  	cogit LogicalShiftRightCq: objectMemory shiftForWord R: instSpecReg.
  	"push fill value"
  	cogit MoveCq: 0 R: TempReg.
  	cogit PushR: TempReg.
  	jumpBytePrepDone := cogit Jump: 0. "go allocate"
  
  	jumpArrayFormat jmpTarget:
  		(cogit CmpCq: (objectMemory integerObjectOf: maxSlots) R: Arg0Reg).
  	jumpArrayTooBig := cogit JumpAbove: 0.
  	"save num elements/slot size to instSpecReg"
  	cogit MoveR: TempReg R: instSpecReg.
  	"push fill value"
  	cogit MoveCw: objectMemory nilObject R: TempReg.
  	cogit PushR: TempReg.
  	"fall through to allocate"
  
  	jumpBytePrepDone jmpTarget:
  	(jumpLongPrepDone jmpTarget: cogit Label).
  
  	"write half header now; it frees halfHeaderReg"
  	cogit MoveR: halfHeaderReg Mw: 0 r: Arg1Reg.
  	"save numSlots to halfHeaderReg"
  	cogit MoveR: instSpecReg R: halfHeaderReg.
  	"compute byte size; remember 0-sized objects still need 1 slot & allocation is
  	 rounded up to 8 bytes."
  	cogit CmpCq: 0 R: byteSizeReg. "a.k.a. instSpecReg"
  	jumpHasSlots := cogit JumpNonZero: 0.
  	cogit MoveCq: objectMemory baseHeaderSize * 2 R: byteSizeReg.
  	skip := cogit Jump: 0.
  	"round up to allocationUnit"
  	jumpHasSlots jmpTarget:
  	(cogit MoveR: byteSizeReg R: TempReg).
  	cogit AndCq: 1 R: TempReg.
  	cogit AddR: TempReg R: byteSizeReg.
  	cogit AddCq: objectMemory baseHeaderSize / objectMemory wordSize R: byteSizeReg.
  	cogit LogicalShiftLeftCq: objectMemory shiftForWord R: byteSizeReg.
  	skip jmpTarget:
  	"shift halfHeaderReg to put numSlots in correct place"
  	(cogit LogicalShiftLeftCq: objectMemory numSlotsHalfShift R: halfHeaderReg).
  	"check if allocation fits"
  	cogit AddR: Arg1Reg R: byteSizeReg.
  	cogit CmpCq: objectMemory getScavengeThreshold R: byteSizeReg.
  	jumpNoSpace := cogit JumpAboveOrEqual: 0.
  	"get result, increment freeStart and write it back. Arg1Reg holds new freeStart, the limit of the object"
  	cogit MoveR: Arg1Reg R: ReceiverResultReg.
  	cogit MoveR: byteSizeReg Aw: objectMemory freeStartAddress.
  	"write other half of header (numSlots/0 identityHash)"
  	cogit MoveR: halfHeaderReg Mw: 4 r: ReceiverResultReg.
  	"now fill"
  	cogit PopR: fillReg.
  	cogit LoadEffectiveAddressMw: objectMemory baseHeaderSize r: ReceiverResultReg R: Arg1Reg.
  	"at least two words; so can make this a [fill 2 words. reached limit?] whileFalse"
  	fillLoop := 
  	cogit MoveR: fillReg Mw: 0 r: Arg1Reg.
  	cogit MoveR: fillReg Mw: 4 r: Arg1Reg.
  	cogit AddCq: 8 R: Arg1Reg.
  	cogit CmpR: Arg1Reg R: byteSizeReg.
  	cogit JumpAbove: fillLoop.
  	cogit RetN: retNoffset.
  
  	"pop discarded fill value & fall through to failure"
  	jumpNoSpace jmpTarget: (cogit PopR: TempReg).
  
  	jumpUnhashed jmpTarget:
  	(jumpFailCuzFixed jmpTarget:
  	(jumpArrayTooBig jmpTarget:
  	(jumpByteTooBig jmpTarget:
  	(jumpLongTooBig jmpTarget:
  	(jumpNElementsNonInt jmpTarget: cogit Label))))).
  
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationFor32BitSpur>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
  genInnerPrimitiveStringAt: retNoffset
  	"Implement the guts of primitiveStringAt; dispatch on size"
  	| formatReg jumpNotIndexable jumpSmallSize jumpBadIndex done
  	  jumpIsBytes jumpIsShorts jumpIsWords jumpWordTooBig
  	  jumpBytesOutOfBounds jumpShortsOutOfBounds jumpWordsOutOfBounds |
  	<inline: true>
  	"c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length:"
  	<var: #done type: #'AbstractInstruction *'>
  	<var: #jumpIsBytes type: #'AbstractInstruction *'>
  	<var: #jumpIsShorts type: #'AbstractInstruction *'>
  	<var: #jumpIsWords type: #'AbstractInstruction *'>
  	<var: #jumpBadIndex type: #'AbstractInstruction *'>
  	<var: #jumpSmallSize type: #'AbstractInstruction *'>
  	<var: #jumpWordTooBig type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpBytesOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortsOutOfBounds type: #'AbstractInstruction *'>
  	<var: #jumpWordsOutOfBounds type: #'AbstractInstruction *'>
  
  	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
  	jumpBadIndex := self genJumpNotSmallIntegerInScratchReg: TempReg.
+ 	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg. "1-rel => 0-rel"
  
  	formatReg := SendNumArgsReg.
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: formatReg;				"formatReg := least significant half of self baseHeader: receiver"
  		MoveR: formatReg R: TempReg;
  		LogicalShiftRightCq: objectMemory formatShift R: formatReg;
  		AndCq: objectMemory formatMask R: formatReg.	"formatReg := self formatOfHeader: destReg"
  
  	"get numSlots into ClassReg."
  	cogit MoveCq: 0 R: ClassReg. "N.B. MoveMb:r:R: does not zero other bits"
  	cogit MoveMb: 7 r: ReceiverResultReg R: ClassReg. "MSB of header"
  	cogit CmpCq: objectMemory numSlotsMask R: ClassReg.
  	jumpSmallSize := cogit JumpLess: 0.
  	cogit MoveMw: -8 r: ReceiverResultReg R: ClassReg. "LSW of overflow size header"
  
  	"dispatch on format in a combination of highest dynamic frequency order first and convenience.
  		  0 = 0 sized objects (UndefinedObject True False et al)
  		  1 = non-indexable objects with inst vars (Point et al)
  		  2 = indexable objects with no inst vars (Array et al)
  		  3 = indexable objects with inst vars (MethodContext AdditionalMethodState et al)
  		  4 = weak indexable objects with inst vars (WeakArray et al)
  		  5 = weak non-indexable objects with inst vars (ephemerons) (Ephemeron)
  		  6 unused, reserved for exotic pointer objects?
  		  7 Forwarded Object, 1st field is pointer, rest of fields are ignored
  		  8 unused, reserved for exotic non-pointer objects?
  		  9 (?) 64-bit indexable
  		10 - 11 32-bit indexable
  		12 - 15 16-bit indexable
  		16 - 23 byte indexable
  		24 - 31 compiled method"
  	jumpSmallSize jmpTarget:
  					(cogit CmpCq: objectMemory firstByteFormat R: formatReg).
  	jumpIsBytes := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory firstShortFormat R: formatReg.
  	jumpIsShorts := cogit JumpGreaterOrEqual: 0.
  					cogit CmpCq: objectMemory firstLongFormat R: formatReg.
  	jumpIsWords := cogit JumpGreaterOrEqual: 0.
  	jumpNotIndexable := cogit Jump: 0.
  
  	jumpIsBytes jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord R: ClassReg).
  		cogit AndCq: objectMemory wordSize - 1 R: formatReg.
  		cogit SubR: formatReg R: ClassReg;
  		CmpR: Arg1Reg R: ClassReg.
  	jumpBytesOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize R: Arg1Reg.
  	cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
  	done := cogit Label.
+ 	self genConvertIntegerToCharacterInReg: ReceiverResultReg.
- 	self genConvertIntegerToCharacterInScratchReg: ReceiverResultReg.
  	cogit RetN: retNoffset.
  
  	jumpIsShorts jmpTarget:
  		(cogit LogicalShiftLeftCq: objectMemory shiftForWord - 1 R: ClassReg).
  		cogit AndCq: 1 R: formatReg.
  		cogit SubR: formatReg R: ClassReg;
  		CmpR: Arg1Reg R: ClassReg.
  	jumpShortsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddR: Arg1Reg R: ReceiverResultReg.
  	cogit MoveM16: objectMemory baseHeaderSize r: ReceiverResultReg R: ReceiverResultReg.
  	cogit Jump: done.
  
  	jumpIsWords jmpTarget:
  		(cogit CmpR: Arg1Reg R: ClassReg).
  	jumpWordsOutOfBounds := cogit JumpBelowOrEqual: 0.
  	cogit AddCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  	cogit MoveXwr: Arg1Reg R: ReceiverResultReg R: TempReg.
  	cogit SubCq: objectMemory baseHeaderSize >> objectMemory shiftForWord R: Arg1Reg.
  	jumpWordTooBig := self jumpNotCharacterUnsignedValueInRegister: TempReg.
  	cogit MoveR: TempReg R: ReceiverResultReg.
  	cogit Jump: done.
  
  	jumpBytesOutOfBounds jmpTarget:
  	(jumpShortsOutOfBounds jmpTarget:
  	(jumpWordsOutOfBounds jmpTarget:
  	(jumpWordTooBig jmpTarget:
  	(jumpNotIndexable jmpTarget: 
  	(jumpBadIndex jmpTarget: cogit Label))))).
  
  	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSpur>>genConvertIntegerToCharacterInReg: (in category 'compile abstract instructions') -----
+ genConvertIntegerToCharacterInReg: reg
+ 	cogit
+ 		LogicalShiftLeftCq: objectMemory numTagBits R: reg;
+ 		AddCq: objectMemory characterTag R: reg.
+ 	^0!

Item was removed:
- ----- Method: CogObjectRepresentationForSpur>>genConvertIntegerToCharacterInScratchReg: (in category 'compile abstract instructions') -----
- genConvertIntegerToCharacterInScratchReg: reg
- 	cogit
- 		LogicalShiftLeftCq: objectMemory numTagBits R: reg;
- 		AddCq: objectMemory characterTag R: reg.
- 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genInnerPrimitiveSize: (in category 'primitive generators') -----
  genInnerPrimitiveSize: retNoffset
  	| jumpImm jumpNotIndexable jumpIsContext |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpImm type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpImm := self genJumpImmediateInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
+ 	self genConvertIntegerToSmallIntegerInReg: ClassReg.
- 	self genConvertIntegerToSmallIntegerInScratchReg: ClassReg.
  	cogit MoveR: ClassReg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpImm jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)).
  	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genConvertIntegerToSmallIntegerInReg: (in category 'compile abstract instructions') -----
+ genConvertIntegerToSmallIntegerInReg: reg
+ 	cogit LogicalShiftLeftCq: 1 R: reg.
+ 	cogit AddCq: 1 R: reg.
+ 	^0!

Item was added:
+ ----- Method: CogObjectRepresentationForSqueakV3>>genConvertSmallIntegerToIntegerInReg: (in category 'compile abstract instructions') -----
+ genConvertSmallIntegerToIntegerInReg: reg
+ 	cogit ArithmeticShiftRightCq: 1 R: reg.
+ 	^0!

Item was removed:
- ----- Method: CogObjectRepresentationForSqueakV3>>genConvertSmallIntegerToIntegerInScratchReg: (in category 'compile abstract instructions') -----
- genConvertSmallIntegerToIntegerInScratchReg: scratchReg
- 	cogit ArithmeticShiftRightCq: 1 R: scratchReg.
- 	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveAt: (in category 'primitive generators') -----
  genInnerPrimitiveAt: retNoffset
  	| jumpSI jumpNotSI jumpNotIndexable jumpIsContext jumpBounds jumpFmtGt4 jumpFmtEq2 jumpFmtLt8 jumpFmtGt11 jumpLarge |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	<var: #jumpBounds type: #'AbstractInstruction *'>
  	<var: #jumpFmtGt4 type: #'AbstractInstruction *'>
  	<var: #jumpFmtEq2 type: #'AbstractInstruction *'>
  	<var: #jumpFmtLt8 type: #'AbstractInstruction *'>
  	<var: #jumpFmtGt11 type: #'AbstractInstruction *'>
  	<var: #jumpLarge type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
  	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
  	jumpNotSI := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
+ 	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg.
  	cogit CmpR: ClassReg R: Arg1Reg.
  	jumpBounds := cogit JumpAboveOrEqual: 0.
  	"This is tedious.  Because of register pressure on x86 (and the baroque
  	 complexity of the size computation) we have to recompute the format
  	 because it may have been smashed computing the fixed fields.  But at
  	 least we have the fixed fields, if any, in formatReg and recomputing
  	 these is more expensive than recomputing format.  In any case this
  	 should still be faster than the interpreter and we hope this object
  	 representation's days are numbered."
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: ClassReg;	"self baseHeader: receiver"
  		LogicalShiftRightCq: objectMemory instFormatFieldLSB R: ClassReg;
  		AndCq: self instFormatFieldMask R: ClassReg;	"self formatOfHeader: ClassReg"
  		CmpCq: 4 R: ClassReg.
  	jumpFmtGt4 := cogit JumpGreater: 0.
  	cogit CmpCq: 2 R: ClassReg.	"Common case, e.g. Array, has format = 2"
  	jumpFmtEq2 := cogit JumpZero: 0.
  	cogit AddR: SendNumArgsReg R: Arg1Reg. "Add fixed fields to index"
  	jumpFmtEq2 jmpTarget: cogit Label.
  	cogit "Too lazy [knackered, more like. ed.] to define index with displacement addressing right now"
  		AddCq: BaseHeaderSize / BytesPerWord R: Arg1Reg;
  		MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg;
  		RetN: retNoffset.
  	jumpFmtGt4 jmpTarget: cogit Label.
  	"Byte objects have formats 8 through 15, Compiled methods being 12 through 15;
  	 fail for CompiledMethod allowing the CoInterpeter to impose stricter bounds checks."
  	cogit CmpCq: 8 R: ClassReg.
  	jumpFmtLt8 := cogit JumpLess: 0.
  	cogit CmpCq: 11 R: ClassReg.
  	jumpFmtGt11 := cogit JumpGreater: 0.
  	cogit
  		AddCq: BaseHeaderSize R: Arg1Reg;
  		MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg.
+ 	self genConvertIntegerToSmallIntegerInReg: ReceiverResultReg.
- 	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpFmtLt8 jmpTarget: cogit Label.
  	self assert: BytesPerWord = 4. "documenting my laziness"
  	cogit "Too lazy [knackered, more like. ed.] to define index with displacement addressing right now"
  		AddCq: BaseHeaderSize / BytesPerWord R: Arg1Reg;
  		MoveXwr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg;
  		CmpCq: 16r3FFFFFFF R: ReceiverResultReg.
  	jumpLarge := cogit JumpAbove: 0.
  	self genConvertIntegerToSmallIntegerInScratchReg: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpLarge jmpTarget: (cogit CallRT: cogit cePositive32BitIntegerTrampoline).
  	cogit
  		MoveR: TempReg R: ReceiverResultReg;
  		RetN: retNoffset.
  	jumpSI jmpTarget:
  	(jumpNotSI jmpTarget:
  	(jumpNotIndexable jmpTarget:
  	(jumpIsContext jmpTarget:
  	(jumpBounds jmpTarget:
  	(jumpFmtGt11 jmpTarget:
  		cogit Label))))).
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveSize: (in category 'primitive generators') -----
  genInnerPrimitiveSize: retNoffset
  	| jumpSI jumpNotIndexable jumpIsContext |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpNotIndexable type: #'AbstractInstruction *'>
  	<var: #jumpIsContext type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
  	self
  		genGetSizeOf: ReceiverResultReg
  		into: ClassReg
  		formatReg: SendNumArgsReg
  		scratchReg: TempReg
  		abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic].
+ 	self genConvertIntegerToSmallIntegerInReg: ClassReg.
- 	self genConvertIntegerToSmallIntegerInScratchReg: ClassReg.
  	cogit MoveR: ClassReg R: ReceiverResultReg.
  	cogit RetN: retNoffset.
  	jumpSI jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)).
  	^0!

Item was changed:
  ----- Method: CogObjectRepresentationForSqueakV3>>genInnerPrimitiveStringAt: (in category 'primitive generators') -----
  genInnerPrimitiveStringAt: retNOffset
  	| jumpSI jumpNotSI jumpNotByteIndexable jumpBounds jumpShortHeader jumpSkip |
  	"c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:"
  	<var: #jumpSI type: #'AbstractInstruction *'>
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpNotByteIndexable type: #'AbstractInstruction *'>
  	<var: #jumpBounds type: #'AbstractInstruction *'>
  	<var: #jumpShortHeader type: #'AbstractInstruction *'>
  	<var: #jumpSkip type: #'AbstractInstruction *'>
  	cogit MoveR: ReceiverResultReg R: TempReg.
  	jumpSI := self genJumpSmallIntegerInScratchReg: TempReg.
  	cogit MoveR: Arg0Reg R: TempReg.
  	cogit MoveR: Arg0Reg R: Arg1Reg.
  	jumpNotSI := self genJumpNotSmallIntegerInScratchReg: TempReg.
  	cogit
  		MoveMw: 0 r: ReceiverResultReg R: TempReg;	"self baseHeader: receiver"
  		MoveR: TempReg R: ClassReg;					"copy header word; we'll need it later"
  		LogicalShiftRightCq: objectMemory instFormatFieldLSB R: TempReg;
  		AndCq: self instFormatFieldMask R: TempReg;	"self formatOfHeader: destReg"
  		MoveR: TempReg R: SendNumArgsReg;
  		AndCq: 3 R: SendNumArgsReg;					"get odd bytes from format (if it turns out to be bytes)"
  		SubR: SendNumArgsReg R: TempReg;
  		CmpCq: 8 R: TempReg.							"check format is 8"
  	jumpNotByteIndexable := cogit JumpNonZero: 0.
  	cogit
  		MoveR: ClassReg R: TempReg;
  		AndCq: TypeMask R: TempReg;
  		CmpCq: HeaderTypeSizeAndClass R: TempReg.	"(hdr bitAnd: TypeMask) = HeaderTypeSizeAndClass"
  	jumpShortHeader := cogit JumpNonZero: 0.
  	self assert: Size4Bit = 0.
  	cogit
  		MoveMw: 0 - (2 * BytesPerWord) r: ReceiverResultReg R: ClassReg; "(self sizeHeader: oop) bitAnd: LongSizeMask"
  		AndCq: LongSizeMask signedIntFromLong R: ClassReg.
  	jumpSkip :=  cogit Jump: 0.
  	jumpShortHeader jmpTarget: (cogit AndCq: SizeMask R: ClassReg).	"hdr bitAnd: SizeMask"
  	jumpSkip jmpTarget: (cogit SubCq: BaseHeaderSize R: ClassReg). "sz - BaseHeaderSize"
  	cogit SubR: SendNumArgsReg R: ClassReg. "sz - (fmt bitAnd: 3)"
+ 	self genConvertSmallIntegerToIntegerInReg: Arg1Reg.
- 	self genConvertSmallIntegerToIntegerInScratchReg: Arg1Reg.
  	cogit SubCq: 1 R: Arg1Reg.
  	cogit CmpR: ClassReg R: Arg1Reg.
  	jumpBounds := cogit JumpAboveOrEqual: 0.
  	cogit AddCq: BaseHeaderSize R: Arg1Reg.
  	cogit annotate: (cogit MoveCw: objectMemory characterTable R: Arg0Reg)
  		objRef: objectMemory characterTable.
  	cogit MoveXbr: Arg1Reg R: ReceiverResultReg R: ReceiverResultReg;
  		AddCq: BaseHeaderSize / BytesPerWord R: ReceiverResultReg.
  	cogit MoveXwr: ReceiverResultReg R: Arg0Reg R: ReceiverResultReg.
  	cogit RetN: retNOffset.
  	jumpSI jmpTarget:
  	(jumpNotSI jmpTarget:
  	(jumpNotByteIndexable jmpTarget:
  	(jumpBounds jmpTarget:
  		cogit Label))).
  	^0!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>compileGetErrorCode (in category 'compile abstract instructions') -----
  compileGetErrorCode
  	"After pushing the temporaries but before the stack limit check a primitive method
  	 needs to fetch the error code, if any, and replace the last temp with it."
  	<inline: false>
  	| jmpNoError primErrorTable primErrorTableSize jmpIntError jmpGotError |
  	<var: #jmpNoError type: #'AbstractInstruction *'>
  	<var: #jmpIntError type: #'AbstractInstruction *'>
  	<var: #jmpGotError type: #'AbstractInstruction *'>
  	self MoveAw: coInterpreter primFailCodeAddress R: TempReg.
  	self flag: 'ask concrete code gen if move sets condition codes?'.
  	self CmpCq: 0 R: TempReg.
  	jmpNoError := self JumpZero: 0.
  	primErrorTable := coInterpreter primErrTable.
  	primErrorTableSize := objectMemory lengthOf: primErrorTable.
  	self flag: 'use CmpCqR if pc mapping means stable contexts never contain native pcs'.
  	"Can't use CmpCqR here because table could change its size.
  	 Assume generated code is flushed whenever primitive error table is changed."
  	self CmpCw: primErrorTableSize R: TempReg.
  	jmpIntError := self JumpAboveOrEqual: 0. "Filter out negative values as well"
  	objectRepresentation genFetchIndexRegister: TempReg from: primErrorTable into: ClassReg.
  	jmpGotError := self Jump: 0.
  	jmpIntError jmpTarget: self Label.
+ 	objectRepresentation genConvertIntegerToSmallIntegerInReg: TempReg.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jmpGotError jmpTarget: (self MoveR: ClassReg Mw: 0 r: SPReg).
  	"zero the error code to agree with the interpreter's (internal)ActivateNewMethod."
  	self MoveCq: 0 R: TempReg.
  	self MoveR: TempReg Aw: coInterpreter primFailCodeAddress.
  	jmpNoError jmpTarget: self Label!

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 MoveMw: BytesPerWord r: SPReg R: TempReg.
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	self MoveR: TempReg R: ClassReg.
  	jumpImmediate := objectRepresentation genJumpImmediateInScratchReg: TempReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: SendNumArgsReg.
  	self CmpCq: objectMemory classFloatCompactIndex R: 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 flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 2.
  	jumpImmediate jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg].
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: 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 MoveMw: BytesPerWord r: SPReg R: TempReg.
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	self MoveR: TempReg R: ClassReg.
  	jumpImmediate := objectRepresentation genJumpImmediateInScratchReg: TempReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: SendNumArgsReg.
  	self CmpCq: objectMemory classFloatCompactIndex R: 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 annotate: (self MoveCw: objectMemory falseObject R: ReceiverResultReg)
  		objRef: objectMemory falseObject.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 2.
  	jumpCond jmpTarget: (self annotate: (self MoveCw: objectMemory trueObject R: ReceiverResultReg)
  							objRef: objectMemory trueObject).
  	self RetN: BytesPerWord * 2.
  	jumpImmediate jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg].
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: ClassReg.
  	self ConvertR: ClassReg Rd: DPFPReg1.
  	self Jump: compare.
  	jumpFail jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt jmpTarget: jumpFail getJmpTarget].
  	^0!

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.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: ClassReg.
  	self ConvertR: ClassReg Rd: DPFPReg0.
  	jumpFailAlloc := objectRepresentation
  					genAllocFloatValue: DPFPReg0
  					into: SendNumArgsReg
  					scratchReg: ClassReg
  					scratchReg: TempReg.
  	self MoveR: SendNumArgsReg R: ReceiverResultReg.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord.
  	jumpFailAlloc jmpTarget: self Label.
  	^self compileFallbackToInterpreterPrimitive!

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 MoveMw: BytesPerWord r: SPReg R: TempReg.
  	self MoveR: TempReg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: 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: BytesPerWord * 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: BytesPerWord * 2.
  	jumpNotSI jmpTarget: (jumpTooBig jmpTarget: (jumpOvfl jmpTarget: self Label)).
  	^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 MoveMw: BytesPerWord 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.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 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 MoveMw: BytesPerWord 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.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 2.
  	jumpOverflow jmpTarget: (jumpInexact jmpTarget: (jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label))).
  	^0!

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 MoveMw: BytesPerWord 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.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 2.
  	jumpOverflow jmpTarget: (jumpZero jmpTarget: (jumpNotSI 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 jumpFail jumpTrue jumpCond |
  	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
  	<var: #jumpDouble type: #'AbstractInstruction *'>
  	<var: #jumpFail type: #'AbstractInstruction *'>
  	<var: #jumpTrue type: #'AbstractInstruction *'>
  	<var: #jumpCond type: #'AbstractInstruction *'>	
  	self MoveMw: BytesPerWord 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 annotate: (self MoveCw: objectMemory falseObject R: ReceiverResultReg)
  		objRef: objectMemory falseObject.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 2.
  	jumpTrue jmpTarget: (self annotate: (self MoveCw: objectMemory trueObject R: ReceiverResultReg)
  						objRef: objectMemory trueObject).
  	self RetN: BytesPerWord * 2.
  	
  	"Argument may be a Float : let us check or fail"
  	jumpDouble jmpTarget: self Label.
  	objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: SendNumArgsReg.
  	self CmpCq: objectMemory classFloatCompactIndex R: 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.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: 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 annotate: (self MoveCw: objectMemory falseObject R: ReceiverResultReg)
  		objRef: objectMemory falseObject.
  	self flag: 'currently caller pushes result'.
  	self RetN: BytesPerWord * 2.
  	jumpCond jmpTarget: (self annotate: (self MoveCw: objectMemory trueObject R: ReceiverResultReg)
  							objRef: objectMemory trueObject).
  	self RetN: BytesPerWord * 2.
  
  	jumpFail jmpTarget: self Label.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genDoubleArithmetic:preOpCheck: (in category 'primitive generators') -----
  genDoubleArithmetic: arithmeticOperator preOpCheck: preOpCheckOrNil
  	"Receiver and arg in registers.
  	 Stack looks like
  		return address"
  	<var: #preOpCheckOrNil declareC: 'AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)'>
  	| jumpFailClass jumpFailAlloc jumpFailCheck jumpImmediate jumpNonInt doOp |
  	<var: #jumpFailClass type: #'AbstractInstruction *'>
  	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
  	<var: #jumpImmediate type: #'AbstractInstruction *'>
  	<var: #jumpNonInt type: #'AbstractInstruction *'>
  	<var: #jumpFailCheck type: #'AbstractInstruction *'>
  	<var: #doOp type: #'AbstractInstruction *'>
  	self MoveR: Arg0Reg R: TempReg.
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	self MoveR: Arg0Reg R: ClassReg.
  	jumpImmediate := objectRepresentation genJumpImmediateInScratchReg: TempReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
  	self CmpCq: objectMemory classFloatCompactIndex R: SendNumArgsReg.
  	jumpFailClass := self JumpNonZero: 0.
  	objectRepresentation genGetDoubleValueOf: Arg0Reg 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: 0.
  	"We need to push the register args on two paths; this one and the interpreter primitive path.
  	But the interpreter primitive path won't unless regArgsHaveBeenPushed is false."
  	self assert: methodOrBlockNumArgs <= self numRegArgs.
  	jumpFailClass jmpTarget: self Label.
  	preOpCheckOrNil ifNotNil:
  		[jumpFailCheck jmpTarget: jumpFailClass getJmpTarget].
  	self genPushRegisterArgsForNumArgs: methodOrBlockNumArgs.
  	jumpFailClass := self Jump: 0.
  	jumpImmediate jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg].
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: ClassReg.
  	self ConvertR: ClassReg Rd: DPFPReg1.
  	self Jump: doOp.
  	jumpFailAlloc jmpTarget: self Label.
  	self compileFallbackToInterpreterPrimitive.
  	jumpFailClass jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt jmpTarget: jumpFailClass getJmpTarget].
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genDoubleComparison:invert: (in category 'primitive generators') -----
  genDoubleComparison: jumpOpcodeGenerator invert: invertComparison
  	"Receiver and arg in registers.
  	 Stack looks like
  		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 MoveR: Arg0Reg R: TempReg.
  	objectRepresentation genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
  	jumpImmediate := objectRepresentation genJumpImmediateInScratchReg: TempReg.
  	objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
  	self CmpCq: objectMemory classFloatCompactIndex R: SendNumArgsReg.
  	jumpFail := self JumpNonZero: 0.
  	objectRepresentation genGetDoubleValueOf: Arg0Reg 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 annotate: (self MoveCw: objectMemory falseObject R: ReceiverResultReg)
  		objRef: objectMemory falseObject.
  	self RetN: 0.
  	jumpCond jmpTarget: (self annotate: (self MoveCw: objectMemory trueObject R: ReceiverResultReg)
  								objRef: objectMemory trueObject).
  	self RetN: 0.
  	jumpImmediate jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg].
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: Arg0Reg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: Arg0Reg.
  	self ConvertR: Arg0Reg Rd: DPFPReg1.
  	self Jump: compare.
  	jumpFail jmpTarget: self Label.
  	objectRepresentation smallIntegerIsOnlyImmediateType ifFalse:
  		[jumpNonInt jmpTarget: jumpFail getJmpTarget].
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveAsFloat (in category 'primitive generators') -----
  genPrimitiveAsFloat
  	| jumpFailAlloc |
  	<var: #jumpFailAlloc type: #'AbstractInstruction *'>
  	self MoveR: ReceiverResultReg R: TempReg.
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: TempReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: TempReg.
  	self ConvertR: TempReg Rd: DPFPReg0.
  	jumpFailAlloc := objectRepresentation
  						genAllocFloatValue: DPFPReg0
  						into: SendNumArgsReg
  						scratchReg: ClassReg
  						scratchReg: TempReg.
  	self MoveR: SendNumArgsReg R: ReceiverResultReg.
  	self RetN: 0.
  	jumpFailAlloc jmpTarget: self Label.
  	^self compileFallbackToInterpreterPrimitive!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveBitShift (in category 'primitive generators') -----
  genPrimitiveBitShift
  	"Receiver and arg in registers.
  	 Stack looks like
  		return address
  
  	rTemp := rArg0
  	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 assert: self numRegArgs >= 1.
  	self MoveR: Arg0Reg R: TempReg.
  	self MoveR: Arg0Reg R: ClassReg.
  	jumpNotSI := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: ClassReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: 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: 0.
  	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: 0.
  	jumpNotSI jmpTarget: (jumpTooBig jmpTarget: (jumpOvfl jmpTarget: self Label)).
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>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 MoveR: Arg0Reg R: TempReg.
  	self MoveR: Arg0Reg R: ClassReg.
  	self MoveR: Arg0Reg 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.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
  	self RetN: 0.
  	"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: StackToRegisterMappingCogit>>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 MoveR: Arg0Reg R: TempReg.
  	self MoveR: Arg0Reg 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.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
  	self RetN: 0.
  	jumpOverflow jmpTarget: (jumpInexact jmpTarget: (jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label))).
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genPrimitiveQuo (in category 'primitive generators') -----
  genPrimitiveQuo
  	| jumpNotSI jumpZero jumpOverflow |
  	<var: #jumpNotSI type: #'AbstractInstruction *'>
  	<var: #jumpZero type: #'AbstractInstruction *'>
  	<var: #jumpOverflow type: #'AbstractInstruction *'>
  	self MoveR: Arg0Reg R: TempReg.
  	self MoveR: Arg0Reg 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.
- 	objectRepresentation genConvertIntegerToSmallIntegerInScratchReg: TempReg.
  	self MoveR: TempReg R: ReceiverResultReg.
  	self RetN: 0.
  	jumpOverflow jmpTarget: (jumpZero jmpTarget: (jumpNotSI jmpTarget: self Label)).
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genSmallIntegerComparison:orDoubleComparison: (in category 'primitive generators') -----
  genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator
  	"Stack looks like
  		return address"
  	| jumpDouble jumpFail jumpTrue jumpCond |
  	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
  	<var: #jumpDouble type: #'AbstractInstruction *'>
  	<var: #jumpFail type: #'AbstractInstruction *'>
  	<var: #jumpTrue type: #'AbstractInstruction *'>
  	<var: #jumpCond type: #'AbstractInstruction *'>	
  	self MoveR: Arg0Reg R: TempReg.
  	jumpDouble := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  	self CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"
  	jumpTrue := self gen: jumpOpcode.
  	self annotate: (self MoveCw: objectMemory falseObject R: ReceiverResultReg)
  		objRef: objectMemory falseObject.
  	self RetN: 0.
  	jumpTrue jmpTarget: (self annotate: (self MoveCw: objectMemory trueObject R: ReceiverResultReg)
  								objRef: objectMemory trueObject).
  	self RetN: 0.
  	
  	"Argument may be a Float : let us check or fail"
  	jumpDouble jmpTarget: self Label.
  	objectRepresentation genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
  	self CmpCq: objectMemory classFloatCompactIndex R: SendNumArgsReg.
  	jumpFail := self JumpNonZero: 0.
  	
  	"It was a Float, so convert the receiver to double and perform the operation"
+ 	objectRepresentation genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.
- 	objectRepresentation genConvertSmallIntegerToIntegerInScratchReg: ReceiverResultReg.
  	self ConvertR: ReceiverResultReg Rd: DPFPReg0.
  	objectRepresentation genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
  	self CmpRd: DPFPReg1 Rd: DPFPReg0.
  	jumpCond := self perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
  	self annotate: (self MoveCw: objectMemory falseObject R: ReceiverResultReg)
  		objRef: objectMemory falseObject.
  	self RetN: 0.
  	jumpCond jmpTarget: (self annotate: (self MoveCw: objectMemory trueObject R: ReceiverResultReg)
  							objRef: objectMemory trueObject).
  	self RetN: 0.
  	jumpFail jmpTarget: self Label.
  	^0!



More information about the Vm-dev mailing list