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

commits at source.squeak.org commits at source.squeak.org
Fri Dec 19 10:00:22 UTC 2014


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

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

Name: VMMaker.oscog-cb.993
Author: cb
Time: 19 December 2014, 10:43:29.176 am
UUID: 94e6546c-43c8-4f3a-a18e-175e5dacd79e
Ancestors: VMMaker.oscog-eem.992

Added inlined primitive code for:
byteNumByte
pointerAt:
byteAt:
pointerAt:put:
byteAt:put:

Variable object inlined primitives are amazingly little because the optimizer ensures the rcvr and args types and range (including second arg range for byteAt:put:) and handles at bytecode level the instSize shifts.

Generated assembly code looks ok but I didn't run it. 

Can you review #genGetNumBytesOf:into: Eliot ? I am not sure how to rewrite that in a single instruction:

	cogit AndCq: objectMemory formatMask R: destReg.
	cogit AndCq: objectMemory wordSize - 1 R: destReg.

I will now try to add code for inlined primitive < <= = ~=

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

Item was added:
+ ----- Method: CogObjectRepresentationFor32BitSpur>>genGetNumBytesOf:into: (in category 'compile abstract instructions') -----
+ genGetNumBytesOf: srcReg into: destReg
+ 	"Get the size in byte-sized slots of the object in srcReg into destReg.
+ 	 srcReg may equal destReg.
+ 	destReg <- numSlots << self shiftForWord - (fmt bitAnd: 7)."
+ 	<var: #jmp type: #'AbstractInstruction'>
+ 	| jmp |
+ 	self genGetRawSlotSizeOfNonImm: srcReg into: TempReg.
+ 	cogit CmpCq: objectMemory numSlotsMask R: TempReg.
+ 	jmp := cogit JumpLess: 0.
+ 	cogit MoveMw: objectMemory wordSize negated r: srcReg R: TempReg.
+ 	jmp jmpTarget: (cogit LogicalShiftLeftCq: objectMemory shiftForWord R: TempReg). 
+ 	"Now: TempReg = numSlots << shiftForWord"
+ 	cogit MoveMw: 0 r: srcReg R: destReg.
+ 	cogit LogicalShiftRightCq: objectMemory formatShift R: destReg. 
+ 	cogit AndCq: objectMemory formatMask R: destReg. 
+ 	cogit AndCq: objectMemory wordSize - 1 R: destReg.
+ 	"Now: fmt bitAnd: 7 in destReg"
+ 	cogit SubR: TempReg R: destReg.
+ 	^0!

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 |
  	(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 SubCq: untaggedVal 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!!!!)"
  
  		"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] ->	[untaggedVal := untaggedVal >> 1.
+ 				self MoveXwr: untaggedVal R: ra R: ra ].
+ 		[65] ->	[untaggedVal := untaggedVal >> 1.
+ 				self MoveXbr: untaggedVal R: ra 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.
  	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!!!!)"
  
  		"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] ->	[self genConvertSmallIntegerToIntegerInReg: rr.
+ 				self MoveXwr: rr R: val R: rr ].
+ 		[65] ->	[self genConvertSmallIntegerToIntegerInReg: rr.
+ 				self MoveXbr: rr R: val R: 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 |
  	(rr := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
  		[self ssAllocateRequiredReg:
  			(rr := optStatus isReceiverResultRegLive
  					ifTrue: [Arg0Reg]
  					ifFalse: [ReceiverResultReg])].
  	(ra := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: rr))) ifNil:
  		[self ssAllocateRequiredReg: (ra := Arg1Reg)].
  	(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!!!!)"
  
  		"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] ->	[self genConvertSmallIntegerToIntegerInReg: rr.
+ 				self MoveXwr: rr R: ra R: ra ].
+ 		[65] ->	[self genConvertSmallIntegerToIntegerInReg: rr.
+ 				self MoveXbr: rr R: ra R: ra ]
  
  	}
  	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:"
+ 
+ 	| ra rr |
+ 	(rr := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
+ 		[self ssAllocateRequiredReg:
+ 			(rr := optStatus isReceiverResultRegLive
+ 					ifTrue: [Arg0Reg]
+ 					ifFalse: [ReceiverResultReg])].
+ 	(ra := backEnd availableRegisterOrNilFor: (self liveRegisters bitOr: (self registerMaskFor: rr))) ifNil:
+ 		[self ssAllocateRequiredReg: (ra := Arg1Reg)].
+ 	(rr = ReceiverResultReg or: [ra = ReceiverResultReg]) ifTrue:
+ 		[optStatus isReceiverResultRegLive: false].
+ 	self ssTop popToReg: TempReg.
+ 	self ssPop: 1.
+ 	self ssTop popToReg: rr.
+ 	self ssPop: 1.
+ 	self ssTop popToReg: ra.
+ 	self ssPop: 1.
+ 	self ssPushRegister: TempReg.
+ 	self genConvertSmallIntegerToIntegerInReg: rr.
+ 	"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] ->	[ self MoveR: TempReg Xwr: rr R: ra ].
+ 		[1] ->	[ self genConvertSmallIntegerToIntegerInReg: TempReg.
+ 				self MoveR: TempReg Xbr: rr R: ra ]
+ 	}
+ 	otherwise: [^EncounteredUnknownBytecode].
+ 
+ 	^0!
- 	"not yet implemented"
- 	^EncounteredUnknownBytecode!

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 |
  	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])]].
  	self ssTop popToReg: rcvrReg.
  	self ssPop: 1.
  	(resultReg := backEnd availableRegisterOrNilFor: self liveRegisters) ifNil:
  		[self ssFlushUpThroughRegister: rcvrReg].
  	prim
  		caseOf: {
  			[1] ->	"01		unchecked pointer numSlots"
  				[resultReg ifNil: [resultReg := rcvrReg].
  				 objectRepresentation
  					genGetNumSlotsOf: rcvrReg into: resultReg;
  					genConvertIntegerToSmallIntegerInScratchReg: resultReg.
  				 self ssPushRegister: resultReg].
+ 			[3] ->	"03 unchecked byte numBytes"
+ 				[resultReg ifNil: [resultReg := rcvrReg].
+ 				 objectRepresentation
+ 					genGetNumBytesOf: rcvrReg into: resultReg;
+ 					genConvertIntegerToSmallIntegerInScratchReg: resultReg.
+ 				 self ssPushRegister: resultReg].
  				  }
  		otherwise:
  			[^EncounteredUnknownBytecode].
  	^0!



More information about the Vm-dev mailing list