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

commits at source.squeak.org commits at source.squeak.org
Fri Nov 21 23:03:35 UTC 2014


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

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

Name: VMMaker.oscog-eem.950
Author: eem
Time: 21 November 2014, 3:00:59.899 pm
UUID: d4d2d679-fd90-48f5-a47a-ebae021776e7
Ancestors: VMMaker.oscog-tpr.949

Fix regression in new primitiveBitShift.
Introduce >>> as an explicitly signed shift.
64-bit ize magnitude64BitIntegerFor:neg:,
positive64BitIntegerFor: & signed64BitIntegerFor:

=============== Diff against VMMaker.oscog-tpr.949 ===============

Item was added:
+ ----- Method: CCodeGenerator>>generateSignedShiftRight:on:indent: (in category 'C translation') -----
+ generateSignedShiftRight: msgNode on: aStream indent: level
+ 	"Generate the C code for >>> onto the given stream."
+ 
+ 	aStream nextPutAll: '((sqInt) '.
+ 	self emitCExpression: msgNode receiver on: aStream.
+ 	aStream nextPutAll: ') >> '.
+ 	self emitCExpression: msgNode args first on: aStream!

Item was changed:
  ----- Method: CCodeGenerator>>initializeCTranslationDictionary (in category 'C translation') -----
  initializeCTranslationDictionary 
  	"Initialize the dictionary mapping message names to actions for C code generation."
  
  	| pairs |
  	
  	translationDict := Dictionary new: 200.
  	pairs := #(
  	#&				#generateAnd:on:indent:
  	#|				#generateOr:on:indent:
  	#and:			#generateSequentialAnd:on:indent:
  	#or:			#generateSequentialOr:on:indent:
  	#not			#generateNot:on:indent:
  
  	#+				#generatePlus:on:indent:
  	#-				#generateMinus:on:indent:
  	#negated		#generateNegated:on:indent:
  	#*				#generateTimes:on:indent:
  	#/				#generateDivide:on:indent:
  	#//				#generateDivide:on:indent:
  	#\\				#generateModulo:on:indent:
  	#<<			#generateShiftLeft:on:indent:
  	#>>			#generateShiftRight:on:indent:
+ 	#>>>			#generateSignedShiftRight:on:indent:
  	#min:			#generateMin:on:indent:
  	#max:			#generateMax:on:indent:
  	#between:and:	#generateBetweenAnd:on:indent:
  
  	#bitAnd:			#generateBitAnd:on:indent:
  	#bitOr:				#generateBitOr:on:indent:
  	#bitXor:			#generateBitXor:on:indent:
  	#bitShift:			#generateBitShift:on:indent:
  	#signedBitShift:	#generateSignedBitShift:on:indent:
  	#bitInvert32		#generateBitInvert:on:indent:
  	#bitInvert64		#generateBitInvert:on:indent:
  	#bitClear:			#generateBitClear:on:indent:
  	#truncateTo:		#generateTruncateTo:on:indent:
  	#rounded			#generateRounded:on:indent:
  
  	#<				#generateLessThan:on:indent:
  	#<=			#generateLessThanOrEqual:on:indent:
  	#=				#generateEqual:on:indent:
  	#>				#generateGreaterThan:on:indent:
  	#>=			#generateGreaterThanOrEqual:on:indent:
  	#~=			#generateNotEqual:on:indent:
  	#==			#generateEqual:on:indent:
  	#~~			#generateNotEqual:on:indent:
  	#isNil			#generateIsNil:on:indent:
  	#notNil			#generateNotNil:on:indent:
  
  	#whileTrue: 	#generateWhileTrue:on:indent:
  	#whileFalse:	#generateWhileFalse:on:indent:
  	#whileTrue 	#generateDoWhileTrue:on:indent:
  	#whileFalse		#generateDoWhileFalse:on:indent:
  	#to:do:			#generateToDo:on:indent:
  	#to:by:do:		#generateToByDo:on:indent:
  	#repeat 		#generateRepeat:on:indent:
  
  	#ifTrue:			#generateIfTrue:on:indent:
  	#ifFalse:		#generateIfFalse:on:indent:
  	#ifTrue:ifFalse:	#generateIfTrueIfFalse:on:indent:
  	#ifFalse:ifTrue:	#generateIfFalseIfTrue:on:indent:
  
  	#ifNotNil:		#generateIfNotNil:on:indent:
  	#ifNil:			#generateIfNil:on:indent:
  	#ifNotNil:ifNil:	#generateIfNotNilIfNil:on:indent:
  	#ifNil:ifNotNil:	#generateIfNilIfNotNil:on:indent:
  
  	#at:				#generateAt:on:indent:
  	#at:put:			#generateAtPut:on:indent:
  	#basicAt:		#generateAt:on:indent:
  	#basicAt:put:	#generateAtPut:on:indent:
  
  	#integerValueOf:			#generateIntegerValueOf:on:indent:
  	#integerObjectOf:			#generateIntegerObjectOf:on:indent:
  	#isIntegerObject: 			#generateIsIntegerObject:on:indent:
  	#cCode:					#generateInlineCCode:on:indent:
  	#cCode:inSmalltalk:			#generateInlineCCode:on:indent:
  	#cPreprocessorDirective:	#generateInlineCPreprocessorDirective:on:indent:
  	#cppIf:ifTrue:ifFalse:		#generateInlineCppIfElse:on:indent:
  	#cppIf:ifTrue:				#generateInlineCppIfElse:on:indent:
  	#cCoerce:to:				#generateCCoercion:on:indent:
  	#cCoerceSimple:to:			#generateCCoercion:on:indent:
  	#addressOf:				#generateAddressOf:on:indent:
  	#addressOf:put:			#generateAddressOf:on:indent:
  	#asAddress:put:			#generateAsAddress:on:indent:
  	#signedIntFromLong		#generateSignedIntFromLong:on:indent:
  	#signedIntToLong			#generateSignedIntToLong:on:indent:
  	#signedIntFromShort		#generateSignedIntFromShort:on:indent:
  	#signedIntToShort			#generateSignedIntToShort:on:indent:
  	#preIncrement				#generatePreIncrement:on:indent:
  	#preDecrement			#generatePreDecrement:on:indent:
  	#inline:						#generateInlineDirective:on:indent:
  	#asFloat					#generateAsFloat:on:indent:
  	#asInteger					#generateAsInteger:on:indent:
  	#asUnsignedInteger		#generateAsUnsignedInteger:on:indent:
  	#asLong					#generateAsLong:on:indent:
  	#asUnsignedLong			#generateAsUnsignedLong:on:indent:
  	#asVoidPointer				#generateAsVoidPointer:on:indent:
  	#asSymbol					#generateAsSymbol:on:indent:
  	#flag:						#generateFlag:on:indent:
  	#anyMask:					#generateBitAnd:on:indent:
  	#noMask:					#generateNoMask:on:indent:
  	#raisedTo:					#generateRaisedTo:on:indent:
  	#touch:						#generateTouch:on:indent:
  
  	#bytesPerOop 				#generateBytesPerOop:on:indent:
  	#bytesPerWord 			#generateBytesPerWord:on:indent:
  	#wordSize		 			#generateBytesPerWord:on:indent:
  	#baseHeaderSize			#generateBaseHeaderSize:on:indent:
  	#minSmallInteger			#generateSmallIntegerConstant:on:indent:
  	#maxSmallInteger			#generateSmallIntegerConstant:on:indent:
  	
  	#sharedCodeNamed:inCase:		#generateSharedCodeDirective:on:indent:
  
  	#perform:							#generatePerform:on:indent:
  	#perform:with:						#generatePerform:on:indent:
  	#perform:with:with:					#generatePerform:on:indent:
  	#perform:with:with:with:				#generatePerform:on:indent:
  	#perform:with:with:with:with:		#generatePerform:on:indent:
  	#perform:with:with:with:with:with:	#generatePerform:on:indent:
  
  	#value								#generateValue:on:indent:
  	#value:								#generateValue:on:indent:
  	#value:value:						#generateValue:on:indent:
  	#value:value:value:					#generateValue:on:indent:
  
  	#deny:								#generateDeny:on:indent:
  
  	#shouldNotImplement				#generateSmalltalkMetaError:on:indent:
  	#shouldBeImplemented			#generateSmalltalkMetaError:on:indent:
  	#subclassResponsibility			#generateSmalltalkMetaError:on:indent:
  	).
  
  	1 to: pairs size by: 2 do: [:i |
  		translationDict at: (pairs at: i) put: (pairs at: i + 1)].
  
  	pairs := #(
  	#ifTrue:					#generateIfTrueAsArgument:on:indent:	
  	#ifFalse:				#generateIfFalseAsArgument:on:indent:
  	#ifTrue:ifFalse:			#generateIfTrueIfFalseAsArgument:on:indent:
  	#ifFalse:ifTrue:			#generateIfFalseIfTrueAsArgument:on:indent:
  	#ifNotNil:				#generateIfNotNilAsArgument:on:indent:	
  	#ifNil:					#generateIfNilAsArgument:on:indent:
  	#ifNotNil:ifNil:			#generateIfNotNilIfNilAsArgument:on:indent:
  	#ifNil:ifNotNil:			#generateIfNilIfNotNilAsArgument:on:indent:
  	#cCode:				#generateInlineCCodeAsArgument:on:indent:
  	#cCode:inSmalltalk:		#generateInlineCCodeAsArgument:on:indent:
  	#cppIf:ifTrue:ifFalse:	#generateInlineCppIfElseAsArgument:on:indent:
  	#cppIf:ifTrue:			#generateInlineCppIfElseAsArgument:on:indent:
  
  	#value					#generateValueAsArgument:on:indent:
  	#value:					#generateValueAsArgument:on:indent:
  	#value:value:			#generateValueAsArgument:on:indent:
  	).
  
  	asArgumentTranslationDict := Dictionary new: 8.
  	1 to: pairs size by: 2 do: [:i |
  		asArgumentTranslationDict at: (pairs at: i) put: (pairs at: i + 1)].
  !

Item was added:
+ ----- Method: Integer>>>>> (in category '*VMMaker-bit manipulation') -----
+ >>> shiftAmount  "right shift, but causes CCodeGenerator to generate a signed shift"
+ 	shiftAmount < 0 ifTrue: [self error: 'negative arg'].
+ 	^self bitShift: 0 - shiftAmount!

Item was changed:
  ----- Method: InterpreterPrimitives>>magnitude64BitIntegerFor:neg: (in category 'primitive support') -----
  magnitude64BitIntegerFor: magnitude neg: isNegative
  	"Return a Large Integer object for the given integer magnitude and sign"
  	| newLargeInteger largeClass intValue highWord sz isSmall smallVal |
  	<var: 'magnitude' type: #usqLong>
  	<var: 'highWord' type: #usqInt>
  
  	isSmall := isNegative
+ 				ifTrue: [magnitude < objectMemory maxSmallInteger]
- 				ifTrue: [magnitude <= (objectMemory maxSmallInteger + 1)]
  				ifFalse: [magnitude < (objectMemory maxSmallInteger + 1)].
  	isSmall ifTrue:
  		[smallVal := self cCoerceSimple: magnitude to: #sqInt.
+ 		 isNegative ifTrue: [smallVal := 0 - smallVal].
+ 		 ^objectMemory integerObjectOf: smallVal].
+ 
- 		isNegative	ifTrue: [smallVal := 0 - smallVal].
- 		^objectMemory integerObjectOf: smallVal].
  	largeClass := isNegative
  					ifTrue: [objectMemory classLargeNegativeInteger]
  					ifFalse: [objectMemory classLargePositiveInteger].
+ 	objectMemory wordSize = 8
+ 		ifTrue: [sz := 8]
- 	highWord := magnitude >> 32.
- 	highWord = 0 
- 		ifTrue: [sz := 4] 
  		ifFalse:
+ 			[(highWord := magnitude >> 32) = 0
+ 				ifTrue: [sz := 4] 
+ 				ifFalse:
+ 					[sz := 5.
+ 					 (highWord := highWord >> 8) = 0 ifFalse:
+ 						[sz := sz + 1.
+ 						 (highWord := highWord >> 8) = 0 ifFalse:
+ 							[sz := sz + 1.
+ 							 (highWord := highWord >> 8) = 0 ifFalse: [sz := sz + 1]]]]].
- 			[sz := 5.
- 			(highWord := highWord >> 8) = 0 ifFalse: [sz := sz + 1].
- 			(highWord := highWord >> 8) = 0 ifFalse: [sz := sz + 1].
- 			(highWord := highWord >> 8) = 0 ifFalse: [sz := sz + 1]].
  	newLargeInteger := objectMemory instantiateClass: largeClass indexableSize:  sz.
  	0 to: sz-1 do: [:i |
  		intValue := (magnitude >> (i * 8)) bitAnd: 255.
  		objectMemory storeByte: i ofObject: newLargeInteger withValue: intValue].
  	^newLargeInteger!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitShift (in category 'arithmetic integer primitives') -----
  primitiveBitShift 
  	| integerReceiver integerArgument shifted |
  	integerArgument := self stackTop.
  	(objectMemory isIntegerObject: integerArgument) ifFalse:
  		[^self primitiveFail].
  	integerReceiver := self stackValue: 1.
  	objectMemory wordSize = 4
  		ifTrue:
  			[integerReceiver := self positive32BitValueOf: integerReceiver]
  		ifFalse:
  			[integerReceiver := self signed64BitValueOf: integerReceiver].
  	self successful ifTrue:
  		[(integerArgument := objectMemory integerValueOf: integerArgument) >= 0
+ 			ifTrue: "Left shift -- must fail bits would be lost"
- 			ifTrue: "Left shift -- must fail if we lose bits beyond 32"
  				[integerArgument <= objectMemory numSmallIntegerBits ifFalse:
  					[^self primitiveFail].
  				shifted := integerReceiver << integerArgument.
+ 				integerReceiver = (objectMemory wordSize = 4
+ 									ifTrue: [shifted >> integerArgument]
+ 									ifFalse: [shifted >>> integerArgument])  ifFalse:
- 				(shifted >> integerArgument) = integerReceiver ifFalse:
  					[^self primitiveFail]]
  			ifFalse: "Right shift -- OK to lose bits"
  				[integerArgument >= objectMemory numSmallIntegerBits negated ifFalse:
  					[^self primitiveFail].
+ 				 shifted := integerReceiver >> (0 - integerArgument)].
+ 		shifted := objectMemory wordSize = 4
+ 					ifTrue: [self positive32BitIntegerFor: shifted]
- 			shifted := integerReceiver >> (0 - integerArgument)].
- 		shifted := (objectMemory isIntegerValue: shifted)
- 					ifTrue: [objectMemory integerObjectOf: shifted]
  					ifFalse:
+ 						[(objectMemory isIntegerValue: shifted)
+ 							ifTrue: [objectMemory integerObjectOf: shifted]
- 						[objectMemory wordSize = 4
- 							ifTrue: [self positive32BitIntegerFor: shifted]
  							ifFalse: [self signed64BitIntegerFor: shifted]].
  		self pop: 2 thenPush: shifted]!

Item was changed:
  ----- Method: StackInterpreter>>positive64BitIntegerFor: (in category 'primitive support') -----
  positive64BitIntegerFor: integerValue
  	<var: 'integerValue' type: #sqLong>
  	"Answer a Large Positive Integer object for the given integer value.  N.B. will *not* cause a GC."
  	| newLargeInteger highWord sz |
+ 	objectMemory wordSize = 8
+ 		ifTrue:
+ 			[(integerValue >= 0 and: [objectMemory isIntegerValue: integerValue]) ifTrue:
+ 				[^objectMemory integerObjectOf: integerValue].
+ 			 sz := 8]
+ 		ifFalse:
+ 			[(highWord := integerValue >>> 32) = 0 ifTrue:
+ 				[^self positive32BitIntegerFor: integerValue].
+ 			 sz := 5.
+ 			 (highWord := highWord >> 8) = 0 ifFalse:
+ 				[sz := sz + 1.
+ 				 (highWord := highWord >> 8) = 0 ifFalse:
+ 					[sz := sz + 1.
+ 					 (highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1]]]].
- 	highWord := self cCode: 'integerValue >> 32' inSmalltalk: [integerValue >> 32]. "shift is coerced to usqInt otherwise"
- 	highWord = 0 ifTrue:[^self positive32BitIntegerFor: integerValue].
- 	sz := 5.
- 	(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1].
- 	(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1].
- 	(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1].
  	newLargeInteger := objectMemory
  							eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
  							format: (objectMemory byteFormatForNumBytes: sz)
  							numSlots: 8 / objectMemory bytesPerOop.
  	objectMemory
  		storeByte: 7 ofObject: newLargeInteger withValue: (integerValue >> 56 bitAnd: 16rFF);
  		storeByte: 6 ofObject: newLargeInteger withValue: (integerValue >> 48 bitAnd: 16rFF);
  		storeByte: 5 ofObject: newLargeInteger withValue: (integerValue >> 40 bitAnd: 16rFF);
  		storeByte: 4 ofObject: newLargeInteger withValue: (integerValue >> 32 bitAnd: 16rFF);
  		storeByte: 3 ofObject: newLargeInteger withValue: (integerValue >> 24 bitAnd: 16rFF);
  		storeByte: 2 ofObject: newLargeInteger withValue: (integerValue >> 16 bitAnd: 16rFF);
  		storeByte: 1 ofObject: newLargeInteger withValue: (integerValue >>   8 bitAnd: 16rFF);
  		storeByte: 0 ofObject: newLargeInteger withValue: (integerValue ">> 0" bitAnd: 16rFF).
  	^newLargeInteger
  !

Item was changed:
  ----- Method: StackInterpreter>>signed64BitIntegerFor: (in category 'primitive support') -----
  signed64BitIntegerFor: integerValue
  	<var: 'integerValue' type: #sqLong>
  	"Answer a Large Integer object for the given integer value.  N.B. will *not* cause a GC."
  	| newLargeInteger magnitude largeClass highWord sz |
  	<inline: false>
  	<var: 'magnitude' type: #sqLong>
  	<var: 'highWord' type: #usqInt>
  
+ 	objectMemory wordSize = 8 ifTrue:
+ 		[(objectMemory isIntegerValue: integerValue) ifTrue:
+ 			[^objectMemory integerObjectOf: integerValue].
+ 		 sz := 8].
+ 
  	integerValue < 0
  		ifTrue:[	largeClass := ClassLargeNegativeIntegerCompactIndex.
  				magnitude := 0 - integerValue]
  		ifFalse:[	largeClass := ClassLargePositiveIntegerCompactIndex.
  				magnitude := integerValue].
  
  	"Make sure to handle the most -ve value correctly. 0 - most -ve = most -ve and most -ve - 1
  	 is +ve.  Alas the simple (negative or: [integerValue - 1 < 0]) fails with contemporary gcc and icc
  	 versions with optimization and sometimes without.  The shift works on all, touch wood."
+ 	
+ 	objectMemory wordSize = 4 ifTrue:
+ 		[(magnitude <= 16r7FFFFFFF
+ 		  and: [integerValue >= 0
+ 			  or: [0 ~= (self cCode: [integerValue << 1]
+ 							inSmalltalk: [integerValue << 1 bitAnd: (1 << 64) - 1])]]) ifTrue:
+ 				[^self signed32BitIntegerFor: integerValue].
- 	(magnitude <= 16r7FFFFFFF
- 	 and: [integerValue >= 0
- 		  or: [0 ~= (self cCode: [integerValue << 1]
- 						inSmalltalk: [integerValue << 1 bitAnd: (1 << 64) - 1])]]) ifTrue:
- 			[^self signed32BitIntegerFor: integerValue].
  
+ 		 (highWord := magnitude >> 32) = 0 
+ 			ifTrue: [sz := 4] 
+ 			ifFalse:
+ 				[sz := 5.
+ 				 (highWord := highWord >> 8) = 0 ifFalse:
+ 					[sz := sz + 1.
+ 					 (highWord := highWord >> 8) = 0 ifFalse:
+ 						[sz := sz + 1.
+ 						 (highWord := highWord >> 8) = 0 ifFalse:
+ 							[sz := sz + 1]]]]].
+ 
- 	highWord := magnitude >> 32.
- 	highWord = 0 
- 		ifTrue:[sz := 4] 
- 		ifFalse:
- 			[sz := 5.
- 			(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1].
- 			(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1].
- 			(highWord := highWord >> 8) = 0 ifFalse:[sz := sz + 1]].
  	newLargeInteger := objectMemory
  							eeInstantiateSmallClassIndex: largeClass
  							format: (objectMemory byteFormatForNumBytes: sz)
  							numSlots: sz + 3 // objectMemory bytesPerOop.
  	sz > 4 ifTrue:
  		[objectMemory
  			storeByte: 7 ofObject: newLargeInteger withValue: (magnitude >> 56 bitAnd: 16rFF);
  			storeByte: 6 ofObject: newLargeInteger withValue: (magnitude >> 48 bitAnd: 16rFF);
  			storeByte: 5 ofObject: newLargeInteger withValue: (magnitude >> 40 bitAnd: 16rFF);
  			storeByte: 4 ofObject: newLargeInteger withValue: (magnitude >> 32 bitAnd: 16rFF)].
  	objectMemory
  		storeByte: 3 ofObject: newLargeInteger withValue: (magnitude >> 24 bitAnd: 16rFF);
  		storeByte: 2 ofObject: newLargeInteger withValue: (magnitude >> 16 bitAnd: 16rFF);
  		storeByte: 1 ofObject: newLargeInteger withValue: (magnitude >>   8 bitAnd: 16rFF);
  		storeByte: 0 ofObject: newLargeInteger withValue: (magnitude ">> 0" bitAnd: 16rFF).
  	^newLargeInteger!



More information about the Vm-dev mailing list