[Vm-dev] VM Maker: VMMaker.oscog-cb.1186.mcz

commits at source.squeak.org commits at source.squeak.org
Mon Apr 13 20:15:24 UTC 2015


ClementBera uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1186.mcz

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

Name: VMMaker.oscog-cb.1186
Author: cb
Time: 13 April 2015, 1:13:39.752 pm
UUID: 238dfa51-a02c-438a-9bd3-5e48cd33b24f
Ancestors: VMMaker.oscog-cb.1185

Added with Eliot some abstraction other register allocation. This is now used in inline primitives.

=============== Diff against VMMaker.oscog-cb.1185 ===============

Item was changed:
  ----- Method: CogAbstractInstruction>>availableRegisterOrNilFor: (in category 'register allocation') -----
  availableRegisterOrNilFor: liveRegsMask
  	"Answer an unused abstract register in the liveRegMask.
  	 Subclasses with more registers can override to answer them."
  	<returnTypeC: #sqInt>
  	self flag: 'searching physical registers that are not assigned to abstract registers first will do a better job and allocate with fewer conflicts'.
+ 	(cogit register: Arg1Reg isInMask: liveRegsMask) ifFalse:
- 	(liveRegsMask anyMask: (cogit registerMaskFor: Arg1Reg)) ifFalse:
  		[^Arg1Reg].
+ 	(cogit register: Arg0Reg isInMask: liveRegsMask) ifFalse:
- 	(liveRegsMask anyMask: (cogit registerMaskFor: Arg0Reg)) ifFalse:
  		[^Arg0Reg].
+ 	(cogit register: SendNumArgsReg isInMask: liveRegsMask) ifFalse:
- 	(liveRegsMask anyMask: (cogit registerMaskFor: SendNumArgsReg)) ifFalse:
  		[^SendNumArgsReg].
+ 	(cogit register: ClassReg isInMask: liveRegsMask) ifFalse:
- 	(liveRegsMask anyMask: (cogit registerMaskFor: ClassReg)) ifFalse:
  		[^ClassReg].
+ 	(cogit register: ReceiverResultReg isInMask: liveRegsMask) ifFalse:
- 	(liveRegsMask anyMask: (cogit registerMaskFor: ReceiverResultReg)) ifFalse:
  		[^ReceiverResultReg].
  	^nil!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>allocateOneRegister (in category 'simulation stack') -----
+ allocateOneRegister
+ 
+ 	| rTop |
+ 
+ 	self ssTop type = SSRegister ifTrue: [ ^ self ssTop register].
+ 	
+ 	rTop := self allocateRegisterNotConflictingWith: 0.
+ 	
+ 	rTop = ReceiverResultReg ifTrue: 
+ 		[ optStatus isReceiverResultRegLive: false ].
+ 	
+ 	^ rTop
+ 	
+ 	!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>allocateRegisterNotConflictingWith: (in category 'simulation stack') -----
+ allocateRegisterNotConflictingWith: registerMask
+ 	| reg |
+ 	"if there's a free register, use it"
+ 	reg := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: registerMask).
+ 	reg ifNotNil: [^ reg].
+ 	"No free register, choose one that does not conflict with registerMask"
+ 	^ self freeRegisterNotConflictingWith: registerMask!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>allocateThreeRegistersInto:thirdIsReceiver: (in category 'simulation stack') -----
+ allocateThreeRegistersInto: trinaryBlock thirdIsReceiver: thirdIsReceiver
+ 	| topRegistersMask rTop rNext rThird needsThirdRegUpdate |
+ 	
+ 	topRegistersMask := 0.
+ 	needsThirdRegUpdate := true.
+ 	
+ 	(self ssTop type = SSRegister and: [ thirdIsReceiver not or: [ self ssTop register ~= ReceiverResultReg ] ]) ifTrue: 
+ 		[ topRegistersMask := self registerMaskFor: (rTop := self ssTop register)].
+ 	((self ssValue: 1) type = SSRegister and: [ thirdIsReceiver not or: [ (self ssValue: 1) register ~= ReceiverResultReg ] ]) ifTrue: 
+ 		[ topRegistersMask := topRegistersMask bitOr: (self registerMaskFor: (rNext := (self ssValue: 1) register))].
+ 	((self ssValue: 2) type = SSRegister and: [thirdIsReceiver not or: [ (self ssValue: 2) register = ReceiverResultReg ] ]) ifTrue: 
+ 		[ needsThirdRegUpdate := false.
+ 		 topRegistersMask := topRegistersMask bitOr: (self registerMaskFor: (rThird := (self ssValue: 2) register))].
+ 	
+ 	rThird ifNil: 
+ 		[ thirdIsReceiver 
+ 			ifTrue: "Is ReceiverResultReg free ?"
+ 				[ rThird := ReceiverResultReg. 
+ 				(self register: ReceiverResultReg isInMask: self liveRegisters) ifTrue: 
+ 					[ self ssAllocateRequiredReg: ReceiverResultReg ] ]
+ 			ifFalse: [ rThird := self allocateRegisterNotConflictingWith: topRegistersMask ].
+ 		topRegistersMask := topRegistersMask bitOr: (self registerMaskFor: rThird) ].
+ 	
+ 	rTop ifNil: [ 
+ 		rTop := self allocateRegisterNotConflictingWith: topRegistersMask.
+ 		topRegistersMask := topRegistersMask bitOr: (self registerMaskFor: rTop) ].
+ 	
+ 	rNext ifNil: [ rNext := self allocateRegisterNotConflictingWith: topRegistersMask ].
+ 	
+ 	(rTop = ReceiverResultReg or: [rNext = ReceiverResultReg or: [rThird = ReceiverResultReg and: [ needsThirdRegUpdate ]]]) ifTrue: 
+ 		[ optStatus isReceiverResultRegLive: false ].
+ 	
+ 	^ trinaryBlock value: rTop value: rNext value: rThird
+ 	
+ 	!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>allocateTwoRegistersInto: (in category 'simulation stack') -----
  allocateTwoRegistersInto: binaryBlock
  	| topRegistersMask rTop rNext |
+ 	
  	topRegistersMask := 0.
+ 	
  	self ssTop type = SSRegister ifTrue: 
  		[ topRegistersMask := self registerMaskFor: (rTop := self ssTop register)].
  	(self ssValue: 1) type = SSRegister ifTrue: 
  		[ topRegistersMask := topRegistersMask bitOr: (self registerMaskFor: (rNext := (self ssValue: 1) register))].
- 	(rTop notNil and: [rNext notNil]) ifTrue: 
- 		[ ^ binaryBlock value: rTop value: rNext ].
  	
+ 	rTop ifNil: [ rTop := self allocateRegisterNotConflictingWith: topRegistersMask ].
- 	rTop ifNotNil:
- 		[ rNext := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: topRegistersMask).
- 		rNext ifNil: 
- 			[ rNext := backEnd availableRegisterOrNilFor: topRegistersMask. 
- 			self assert: rNext notNil.
- 			self ssAllocateRequiredRegMask: rNext upThrough: simStackPtr - 1 ].
- 		^ binaryBlock value: rTop value: rNext ].
  	
+ 	rNext ifNil: [ rNext := self allocateRegisterNotConflictingWith: (self registerMaskFor: rTop) ].
- 	rNext ifNotNil:
- 		[ rTop := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: topRegistersMask).
- 		rTop ifNil: 
- 			[ rTop := backEnd availableRegisterOrNilFor: topRegistersMask. 
- 			self assert: rTop notNil.
- 			self ssAllocateRequiredRegMask: rTop upThrough: simStackPtr - 2 ].
- 		^ binaryBlock value: rTop value: rNext ].
  	
+ 	(rTop = ReceiverResultReg or: [rNext = ReceiverResultReg]) ifTrue: 
+ 		[ optStatus isReceiverResultRegLive: false ].
- 	rTop := backEnd availableRegisterOrNilFor: self liveRegisters.
- 	topRegistersMask := rTop ifNotNil: [ self registerMaskFor: rTop ] ifNil: [0].
- 	rNext := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: topRegistersMask).
- 	(rTop notNil and: [ rNext notNil ]) ifTrue: 
- 		[ ^ binaryBlock value: rTop value: rNext ].
  	
+ 	^ binaryBlock value: rTop value: rNext
- 	rTop ifNil: [ ^ self spillTwoRegistersInto: binaryBlock ].
  	
- 	"rNext isNil. rTop is allocated"
- 	rNext := backEnd availableRegisterOrNilFor: topRegistersMask. 
- 	self assert: rNext notNil.
- 	self ssAllocateRequiredRegMask: rNext upThrough: simStackPtr - 1.
- 	^ binaryBlock value: rTop value: rNext 
  	!

Item was added:
+ ----- Method: StackToRegisterMappingCogit>>freeRegisterNotConflictingWith: (in category 'simulation stack') -----
+ freeRegisterNotConflictingWith: registerMask
+ 	"Spill the closest register on stack not conflicting with registerMask. 
+ 	Assertion Failure if registerMask has already all the registers"
+ 	<var: #desc type: #'CogSimStackEntry *'>
+ 	| reg index |
+ 	index := simSpillBase max: 0.
+ 	[reg isNil and: [index < simStackPtr] ] whileTrue: 
+ 		[ | desc |
+ 		 desc := self simStackAt: index.
+ 		 desc type = SSRegister ifTrue:
+ 			[ (registerMask anyMask: (self registerMaskFor: desc register)) ifFalse: 
+ 				[ reg := desc register ] ].
+ 		 index := index + 1].
+ 	self assert: reg notNil.
+ 	self ssAllocateRequiredReg: reg.
+ 	^reg!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genBinaryConstOpVarInlinePrimitive: (in category 'inline primitive generators') -----
  genBinaryConstOpVarInlinePrimitive: prim
  	"Const op var version of binary inline primitives."
  	"SistaV1: 248		11111000 	iiiiiiii		mjjjjjjj		Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
  	 See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
  	| ra val untaggedVal adjust |
+ 	ra := self allocateOneRegister.
- 	(ra := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
- 		[self ssAllocateRequiredReg:
- 			(ra := optStatus isReceiverResultRegLive
- 					ifTrue: [Arg0Reg]
- 					ifFalse: [ReceiverResultReg])].
- 	ra = ReceiverResultReg ifTrue:
- 		[optStatus isReceiverResultRegLive: false].
  	self ssTop popToReg: ra.
  	self ssPop: 1.
  	val := self ssTop constant.
  	self ssPop: 1.
  	untaggedVal := val - objectMemory smallIntegerTag.
  	prim caseOf: {
  		"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  		[0]	->	[self AddCq: untaggedVal R: ra].
  		[1]	->	[self MoveCq: val R: TempReg.
  				 self SubR: ra R: TempReg.
  				 objectRepresentation genAddSmallIntegerTagsTo: TempReg.
  				 self MoveR: TempReg R: ra].
  		[2]	->	[objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ra.
  				 self MoveCq: (objectMemory integerValueOf: val) R: TempReg.
  				 self MulR: TempReg R: ra.
  				 objectRepresentation genAddSmallIntegerTagsTo: ra].
  
  		"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  
  		"2032	through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)"
  		[32] -> [ self CmpCq: val R: ra.
  				self genBinaryInlineComparison: JumpGreater opFalse: JumpLess destReg: ra ].
  		[33] -> [ self CmpCq: val R: ra.
  				self genBinaryInlineComparison: JumpLess opFalse: JumpGreater destReg: ra ].
  		[34] -> [ self CmpCq: val R: ra.
  				self genBinaryInlineComparison: JumpGreaterOrEqual opFalse: JumpLessOrEqual destReg: ra ].
  		[35] -> [ self CmpCq: val R: ra.
  				self genBinaryInlineComparison: JumpLessOrEqual opFalse: JumpGreaterOrEqual destReg: ra ].
  		[36] -> [ self CmpCq: val R: ra.
  				self genBinaryInlineComparison: JumpZero opFalse: JumpNonZero destReg: ra ].
  		[37] -> [ self CmpCq: val R: ra.
  				self genBinaryInlineComparison: JumpNonZero opFalse: JumpZero destReg: ra ].
  
  		"2064	through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
  		[64] ->	[objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
  				adjust := (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
  				adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra. ]. 
  				self annotate: (self MoveCw: val R: TempReg) objRef: val.
  				self MoveXwr: ra R: TempReg R: ra].
  		[65] ->	[objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
  				adjust := objectMemory baseHeaderSize - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
  				self AddCq: adjust R: ra.
  				self annotate: (self MoveCw: val R: TempReg) objRef: val.
  				self MoveXbr: ra R: TempReg R: ra]
  
  	}
  	otherwise: [^EncounteredUnknownBytecode].
  	self ssPushRegister: ra.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genBinaryVarOpConstInlinePrimitive: (in category 'inline primitive generators') -----
  genBinaryVarOpConstInlinePrimitive: prim
  	"Var op const version of inline binary inline primitives."
  	"SistaV1: 248		11111000 	iiiiiiii		mjjjjjjj		Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
  	 See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
  	| rr val untaggedVal |
- 	(rr := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
- 		[self ssAllocateRequiredReg:
- 			(rr := optStatus isReceiverResultRegLive
- 					ifTrue: [Arg0Reg]
- 					ifFalse: [ReceiverResultReg])].
- 	rr = ReceiverResultReg ifTrue:
- 		[optStatus isReceiverResultRegLive: false].
  	val := self ssTop constant.
  	self ssPop: 1.
+ 	rr := self allocateOneRegister.
  	self ssTop popToReg: rr.
  	self ssPop: 1.
  	untaggedVal := val - objectMemory smallIntegerTag.
  	prim caseOf: {
  		"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  		[0]	->	[self AddCq: untaggedVal R: rr].
  		[1]	->	[self SubCq: untaggedVal R: rr ].
  		[2]	->	[self flag: 'could use MulCq:R'.
  				 objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: rr.
  				 self MoveCq: (objectMemory integerValueOf: val) R: TempReg.
  				 self MulR: TempReg R: rr.
  				 objectRepresentation genAddSmallIntegerTagsTo: rr].
  
  		"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  
  		"2032	through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)
  		Here the comparison is reversed (cst on the left, reg on the right) so I inverted opTrue and opFalse"
  		[32] -> [ self CmpCq: val R: rr.
  				self genBinaryInlineComparison: JumpLess opFalse: JumpGreater destReg: rr ].
  		[33] -> [ self CmpCq: val R: rr.
  				self genBinaryInlineComparison: JumpGreater opFalse: JumpLess destReg: rr ].
  		[34] -> [ self CmpCq: val R: rr.
  				self genBinaryInlineComparison: JumpLessOrEqual opFalse: JumpGreaterOrEqual destReg: rr ].
  		[35] -> [ self CmpCq: val R: rr.
  				self genBinaryInlineComparison: JumpGreaterOrEqual opFalse: JumpLessOrEqual destReg: rr ].
  		[36] -> [ self CmpCq: val R: rr.
  				self genBinaryInlineComparison: JumpNonZero opFalse: JumpZero destReg: rr ].
  		[37] -> [ self CmpCq: val R: rr.
  				self genBinaryInlineComparison: JumpZero opFalse: JumpNonZero destReg: rr ].
  
  		"2064	through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
  		[64] ->	[objectRepresentation genLoadSlot: (objectMemory integerValueOf: val) - 1 sourceReg: rr destReg: rr].
  		[65] ->	[self MoveCq: (objectMemory integerValueOf: val) + objectMemory baseHeaderSize - 1 R: TempReg.
  				self MoveXbr: TempReg R: rr R: rr.
  				objectRepresentation genConvertIntegerToSmallIntegerInReg: rr]
  
  	}
  	otherwise: [^EncounteredUnknownBytecode].
  	self ssPushRegister: rr.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genBinaryVarOpVarInlinePrimitive: (in category 'inline primitive generators') -----
  genBinaryVarOpVarInlinePrimitive: prim
  	"Var op var version of binary inline primitives."
  	"SistaV1: 248		11111000 	iiiiiiii		mjjjjjjj		Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
  	 See EncoderForSistaV1's class comment and StackInterpreter>>#binaryInlinePrimitive:"
  	| ra rr adjust |
  	self allocateTwoRegistersInto: [:rTop :rNext | ra := rTop. rr := rNext ].
- 	(rr = ReceiverResultReg or: [ra = ReceiverResultReg]) ifTrue: [ optStatus isReceiverResultRegLive: false ].
  	self ssTop popToReg: ra.
  	self ssPop: 1.
  	self ssTop popToReg: rr.
  	self ssPop: 1.
  	prim caseOf: {
  		"0 through 6, +, -, *, /, //, \\, quo:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  		[0]	->	[objectRepresentation genRemoveSmallIntegerTagsInScratchReg: ra.
  				 self AddR: ra R: rr].
  		[1]	->	[self SubR: ra R: rr.
  				 objectRepresentation genAddSmallIntegerTagsTo: rr].
  		[2]	->	[objectRepresentation genRemoveSmallIntegerTagsInScratchReg: rr.
  				 objectRepresentation genShiftAwaySmallIntegerTagsInScratchReg: ra.
  				 self MulR: ra R: rr.
  				 objectRepresentation genAddSmallIntegerTagsTo: rr].
  
  		"2016 through 2019, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
  
  		"2032	through 2037, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)"
  		[32] -> [ self CmpR: rr R: ra.
  				self genBinaryInlineComparison: JumpGreater opFalse: JumpLess destReg: rr ].
  		[33] -> [ self CmpR: rr R: ra.
  				self genBinaryInlineComparison: JumpLess opFalse: JumpGreater destReg: rr ].
  		[34] -> [ self CmpR: rr R: ra.
  				self genBinaryInlineComparison: JumpGreaterOrEqual opFalse: JumpLessOrEqual destReg: rr ].
  		[35] -> [ self CmpR: rr R: ra.
  				self genBinaryInlineComparison: JumpLessOrEqual opFalse: JumpGreaterOrEqual destReg: rr ].
  		[36] -> [ self CmpR: rr R: ra.
  				self genBinaryInlineComparison: JumpZero opFalse: JumpNonZero destReg: rr ].
  		[37] -> [ self CmpR: rr R: ra.
  				self genBinaryInlineComparison: JumpNonZero opFalse: JumpZero destReg: rr ].
  
  		"2064	through 2068, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
  		[64] ->	[objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
  				adjust := (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
  				adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra. ]. 
  				self MoveXwr: ra R: rr R: rr ].
  		[65] ->	[objectRepresentation genConvertSmallIntegerToIntegerInReg: ra.
  				adjust := objectMemory baseHeaderSize - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
  				self AddCq: adjust R: ra.
  				self MoveXbr: ra R: rr R: rr.
  				objectRepresentation genConvertIntegerToSmallIntegerInReg: rr]
  
  	}
  	otherwise: [^EncounteredUnknownBytecode].
  	self ssPushRegister: rr.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genTrinaryInlinePrimitive: (in category 'inline primitive generators') -----
  genTrinaryInlinePrimitive: prim
  	"Unary inline primitives."
  	"SistaV1: 248		11111000 	iiiiiiii		mjjjjjjj		Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
  	 See EncoderForSistaV1's class comment and StackInterpreter>>#trinaryInlinePrimitive:"
  
  	| ra1 ra2 rr adjust |
+ 	"The store check requires rr to be ReceiverResultReg"
+ 	self allocateThreeRegistersInto: [:rTop :rNext :rThird | ra2 := rTop. ra1 := rNext. rr := rThird ] thirdIsReceiver: prim = 0.
- 	(ra2 := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
- 		[self ssAllocateRequiredReg: (ra2 := Arg1Reg)].
- 	(ra1 := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: ra2))) ifNil:
- 		[self ssAllocateRequiredReg: (ra1 := Arg0Reg)].
- 	prim = 0
- 		ifTrue:
- 			[rr := ReceiverResultReg.
- 			 ((self ssValue: 2) type = SSRegister
- 			  and: [(self ssValue: 2) register = ReceiverResultReg]) ifFalse:
- 				[self ssAllocateRequiredReg: rr]]
- 		ifFalse:
- 			[(rr := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: ra1 and: ra2))) ifNil:
- 				[self ssAllocateRequiredReg: (rr := ReceiverResultReg)].
- 			 optStatus isReceiverResultRegLive: false].
  	self assert: (rr ~= ra1 and: [rr ~= ra2 and: [ra1 ~= ra2]]).
  	self ssTop popToReg: ra2.
  	self ssPop: 1.
  	self ssTop popToReg: ra1.
  	self ssPop: 1.
  	self ssTop popToReg: rr.
  	self ssPop: 1.
  	objectRepresentation genConvertSmallIntegerToIntegerInReg: ra1.
  	"Now: ra is the variable object, rr is long, TempReg holds the value to store."
  	prim caseOf: {
  		"0 - 1 pointerAt:put: and byteAt:Put:"
  		[0] ->	[ adjust := (objectMemory baseHeaderSize >> objectMemory shiftForWord) - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
  				adjust ~= 0 ifTrue: [ self AddCq: adjust R: ra1. ]. 
  				self MoveR: ra2 Xwr: ra1 R: rr.
  				objectRepresentation genStoreCheckReceiverReg: rr valueReg: ra2 scratchReg: TempReg].
  		[1] ->	[ objectRepresentation genConvertSmallIntegerToIntegerInReg: ra2.
  				adjust := objectMemory baseHeaderSize - 1. "shift by baseHeaderSize and then move from 1 relative to zero relative"
  				self AddCq: adjust R: ra1.
  				self MoveR: ra2 Xbr: ra1 R: rr.
  				objectRepresentation genConvertIntegerToSmallIntegerInReg: ra2. ]
  	}
  	otherwise: [^EncounteredUnknownBytecode].
  	self ssPushRegister: ra2.
  	^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genUnaryInlinePrimitive: (in category 'inline primitive generators') -----
  genUnaryInlinePrimitive: prim
  	"Unary inline primitives."
  	"SistaV1: 248		11111000 	iiiiiiii		mjjjjjjj		Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1 means inlined primitive, no hard return after execution.
  	 See EncoderForSistaV1's class comment and StackInterpreter>>#unaryInlinePrimitive:"
  	| rcvrReg resultReg |
+ 	rcvrReg := self allocateOneRegister.
+ 	resultReg := self allocateRegisterNotConflictingWith: (self registerMaskFor: rcvrReg).
- 	self ssTop type = SSRegister
- 		ifTrue: [rcvrReg := self ssTop register]
- 		ifFalse:
- 			[(rcvrReg := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
- 				[self ssAllocateRequiredReg:
- 					(rcvrReg := optStatus isReceiverResultRegLive
- 							ifTrue: [Arg0Reg]
- 							ifFalse: [ReceiverResultReg])]].
- 	(resultReg := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: rcvrReg))) ifNil:
- 		[self ssAllocateRequiredReg: (resultReg := Arg1Reg)].
  	self ssTop popToReg: rcvrReg.
  	self ssPop: 1.
  	prim
  		caseOf: {
  					"00		unchecked class"
  			[1] ->	"01		unchecked pointer numSlots"
  				[objectRepresentation
  					genGetNumSlotsOf: rcvrReg into: resultReg;
  					genConvertIntegerToSmallIntegerInReg: resultReg].
  					"02		unchecked pointer basicSize"
  			[3] ->	"03		unchecked byte numBytes"
  				[objectRepresentation
  					genGetNumBytesOf: rcvrReg into: resultReg;
  					genConvertIntegerToSmallIntegerInReg: resultReg].
  					"04		unchecked short16Type format numShorts"
  					"05		unchecked word32Type format numWords"
  					"06		unchecked doubleWord64Type format numDoubleWords"
  				  }
  		otherwise:
  			[^EncounteredUnknownBytecode]..
  	self ssPushRegister: resultReg.
  	^0!

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

Item was removed:
- ----- Method: StackToRegisterMappingCogit>>spillTwoRegistersInto: (in category 'simulation stack') -----
- spillTwoRegistersInto: binaryBlock
- 	"Any occurrences on the stack of the register must be
- 	 flushed, and hence any values colder than them stack."
- 	<var: #desc type: #'CogSimStackEntry *'>
- 	| r1 r2 index |
- 	index := simSpillBase max: 0.
- 	[r1 notNil and: [r2 notNil and: [index < simStackPtr]]] whileTrue:
- 		[| desc |
- 		 desc := self simStackAt: index.
- 		 desc type = SSRegister ifTrue:
- 			[ r1
- 				ifNil: [r1 := desc register]
- 				ifNotNil: [r1 ~= desc register ifTrue:
- 							[r2 := desc register]]].
- 		 index := index + 1].
- 	self assert: (r1 notNil and: [r2 notNil]).
- 	self ssAllocateRequiredReg: r1 and: r2.
- 	^binaryBlock value: r1 value: r2!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>ssAllocatePreferredReg: (in category 'simulation stack') -----
  ssAllocatePreferredReg: preferredReg
  	| preferredMask lastPreferred liveRegs |
  	lastPreferred := -1.
  	"compute live regs while noting the last occurrence of preferredReg.
  	 If there are none free we must spill from simSpillBase to last occurrence."
  	preferredMask := (self registerMaskFor: preferredReg).
  	liveRegs := self registerMaskFor: TempReg and: FPReg and: SPReg.
  	(simSpillBase max: 0) to: simStackPtr do:
  		[:i|
  		liveRegs := liveRegs bitOr: (self simStackAt: i) registerMask.
  		(liveRegs bitAnd: preferredMask) ~= 0 ifTrue:
  			[lastPreferred := i]].
  	"If preferredReg is not live we can allocate it."
+ 	(self register: preferredReg isInMask: liveRegs) ifFalse:
- 	(liveRegs bitAnd: (self registerMaskFor: preferredReg)) = 0 ifTrue:
  		[^preferredReg].
  	"If any other is not live we can allocate it."
  	GPRegMin to: GPRegMax do:
  		[:reg|
+ 		(self register: reg isInMask: liveRegs) ifFalse:
- 		(liveRegs bitAnd: (self registerMaskFor: reg)) = 0 ifTrue:
  			[^reg]].
  	"All live, must spill"
  	self ssFlushTo: lastPreferred.
  	self assert: (self liveRegisters bitAnd: preferredMask) = 0.
  	^preferredReg!



More information about the Vm-dev mailing list