[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