VM Maker: VMMaker.oscog-eem.1054.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.1054.mcz

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

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

Name: VMMaker.oscog-eem.1054
Author: eem
Time: 11 February 2015, 1:20:01.475 pm
UUID: 3d511797-53fc-4848-b1ec-4b8a1eb0c0ff
Ancestors: VMMaker.oscog-eem.1053

Broaden primitiveBitAnd and primitiveBitOr for Spur
64-bits.  Make the bytecodes handle the common
SmallInteger op SmallInteger case.

Fix C code for and endianness under simulation of
Spur64BitMemoryManager>>fetchLong32:ofFloatObject:

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

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category 'arithmetic integer primitives') -----
  primitiveBitAnd
+ <inline: false>
  | integerReceiver integerArgument |
+ integerArgument := self stackTop.
+ integerReceiver := self stackValue: 1.
+ "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+ ((objectMemory isIntegerObject: integerArgument)
+ and: [objectMemory isIntegerObject: integerReceiver])
+ ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd: integerReceiver)]
+ ifFalse:
+ ["objectMemory wordSize = 8
+ ifTrue:
+ [integerArgument := self positive64BitValueOf: integerArgument.
+ integerReceiver := self positive64BitValueOf: integerReceiver.
+ self successful ifTrue:
+ [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]
+ ifFalse:
+ [integerArgument := self positive32BitValueOf: integerArgument.
+ integerReceiver := self positive32BitValueOf: integerReceiver.
+ self successful ifTrue:
+ [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]"]"!
- integerArgument := self popPos32BitInteger.
- integerReceiver := self popPos32BitInteger.
- self successful
- ifTrue: [self push: (self positive32BitIntegerFor:
- (integerReceiver bitAnd: integerArgument))]
- ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitOr (in category 'arithmetic integer primitives') -----
  primitiveBitOr
+ <inline: false>
  | integerReceiver integerArgument |
+ integerArgument := self stackTop.
+ integerReceiver := self stackValue: 1.
+ "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+ ((objectMemory isIntegerObject: integerArgument)
+ and: [objectMemory isIntegerObject: integerReceiver])
+ ifTrue: [self pop: 2 thenPush: (integerArgument bitOr: integerReceiver)]
+ ifFalse:
+ ["objectMemory wordSize = 8
+ ifTrue:
+ [integerArgument := self positive64BitValueOf: integerArgument.
+ integerReceiver := self positive64BitValueOf: integerReceiver.
+ self successful ifTrue:
+ [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]
+ ifFalse:
+ [integerArgument := self positive32BitValueOf: integerArgument.
+ integerReceiver := self positive32BitValueOf: integerReceiver.
+ self successful ifTrue:
+ [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitOr: integerReceiver))]]"]"!
- integerArgument := self popPos32BitInteger.
- integerReceiver := self popPos32BitInteger.
- self successful
- ifTrue: [self push: (self positive32BitIntegerFor:
- (integerReceiver bitOr: integerArgument))]
- ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') -----
  fetchLong32: fieldIndex ofFloatObject: oop
  "index by word size, and return a pointer as long as the word size"
 
  | bits |
  (self isImmediateFloat: oop) ifFalse:
  [^self fetchLong32: fieldIndex ofObject: oop].
  bits := self smallFloatBitsOf: oop.
  ^self
+ cCode: [(self cCoerceSimple: (self addressOf: bits) to: #'int *') at: fieldIndex]
+ inSmalltalk:
+ [self flag: #endian.
+ fieldIndex = 0
+ ifTrue: [bits bitAnd: 16rFFFFFFFF]
+ ifFalse: [bits >> 32]]!
- cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *')
- + (fieldIndex << self shiftForWord)]
- inSmalltalk: [self flag: #endian.
- fieldIndex = 0
- ifTrue: [bits >> 32]
- ifFalse: [bits bitAnd: 16rFFFFFFFF]]!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitAnd (in category 'common selector sends') -----
  bytecodePrimBitAnd
+ | rcvr arg |
+ arg := self internalStackTop.
+ rcvr := self internalStackValue: 1.
+ ((objectMemory isIntegerObject: arg)
+ and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+ [self internalPop: 2 thenPush: (arg bitAnd: rcvr).
+ ^self fetchNextBytecode "success"].
 
  self initPrimCall.
  self externalizeIPandSP.
  self primitiveBitAnd.
  self internalizeIPandSP.
+ self successful ifTrue:
+ [^self fetchNextBytecode "success"].
- self successful ifTrue: [^ self fetchNextBytecode "success"].
 
  messageSelector := self specialSelector: 14.
  argumentCount := 1.
  self normalSend!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitOr (in category 'common selector sends') -----
  bytecodePrimBitOr
+ | rcvr arg |
+ arg := self internalStackTop.
+ rcvr := self internalStackValue: 1.
+ ((objectMemory isIntegerObject: arg)
+ and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+ [self internalPop: 2 thenPush: (arg bitOr: rcvr).
+ ^self fetchNextBytecode "success"].
 
  self initPrimCall.
  self externalizeIPandSP.
  self primitiveBitOr.
  self internalizeIPandSP.
+ self successful ifTrue:
+ [^self fetchNextBytecode "success"].
- self successful ifTrue: [^ self fetchNextBytecode "success"].
 
  messageSelector := self specialSelector: 15.
  argumentCount := 1.
  self normalSend!

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1054.mcz

Nicolas Cellier
 
If I reformulate:

1) there is a speed-up consisting in bitAnd'ing bitOr'ing the Oop (shifted integer value+tag) directly without need to decode anything when both are immediate SmallInteger

2) this speed-up is already performed in interpreter special bytecode handling and/or in JIT

3) so checking again in the primitive is a loss of time

4) the primitive is there just in case the receiver and/or argument is a LargePositiveInteger outside immediate range, but still fitting in an unsigned long (32 or 64 bits)

2015-02-11 22:20 GMT+01:00 <[hidden email]>:

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

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

Name: VMMaker.oscog-eem.1054
Author: eem
Time: 11 February 2015, 1:20:01.475 pm
UUID: 3d511797-53fc-4848-b1ec-4b8a1eb0c0ff
Ancestors: VMMaker.oscog-eem.1053

Broaden primitiveBitAnd and primitiveBitOr for Spur
64-bits.  Make the bytecodes handle the common
SmallInteger op SmallInteger case.

Fix C code for and endianness under simulation of
Spur64BitMemoryManager>>fetchLong32:ofFloatObject:

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

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category 'arithmetic integer primitives') -----
  primitiveBitAnd
+       <inline: false>
        | integerReceiver integerArgument |
+       integerArgument := self stackTop.
+       integerReceiver := self stackValue: 1.
+       "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+        ((objectMemory isIntegerObject: integerArgument)
+        and: [objectMemory isIntegerObject: integerReceiver])
+               ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd: integerReceiver)]
+               ifFalse:
+                       ["objectMemory wordSize = 8
+                               ifTrue:
+                                       [integerArgument := self positive64BitValueOf: integerArgument.
+                                        integerReceiver := self positive64BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]
+                               ifFalse:
+                                       [integerArgument := self positive32BitValueOf: integerArgument.
+                                        integerReceiver := self positive32BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]"]"!
-       integerArgument := self popPos32BitInteger.
-       integerReceiver := self popPos32BitInteger.
-       self successful
-               ifTrue: [self push: (self positive32BitIntegerFor:
-                                       (integerReceiver bitAnd: integerArgument))]
-               ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitOr (in category 'arithmetic integer primitives') -----
  primitiveBitOr
+       <inline: false>
        | integerReceiver integerArgument |
+       integerArgument := self stackTop.
+       integerReceiver := self stackValue: 1.
+       "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+        ((objectMemory isIntegerObject: integerArgument)
+        and: [objectMemory isIntegerObject: integerReceiver])
+               ifTrue: [self pop: 2 thenPush: (integerArgument bitOr: integerReceiver)]
+               ifFalse:
+                       ["objectMemory wordSize = 8
+                               ifTrue:
+                                       [integerArgument := self positive64BitValueOf: integerArgument.
+                                        integerReceiver := self positive64BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]
+                               ifFalse:
+                                       [integerArgument := self positive32BitValueOf: integerArgument.
+                                        integerReceiver := self positive32BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitOr: integerReceiver))]]"]"!
-       integerArgument := self popPos32BitInteger.
-       integerReceiver := self popPos32BitInteger.
-       self successful
-               ifTrue: [self push: (self positive32BitIntegerFor:
-                                       (integerReceiver bitOr: integerArgument))]
-               ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') -----
  fetchLong32: fieldIndex ofFloatObject: oop
        "index by word size, and return a pointer as long as the word size"

        | bits |
        (self isImmediateFloat: oop) ifFalse:
                [^self fetchLong32: fieldIndex ofObject: oop].
        bits := self smallFloatBitsOf: oop.
        ^self
+               cCode: [(self cCoerceSimple: (self addressOf: bits) to: #'int *') at: fieldIndex]
+               inSmalltalk:
+                       [self flag: #endian.
+                        fieldIndex = 0
+                               ifTrue: [bits bitAnd: 16rFFFFFFFF]
+                               ifFalse: [bits >> 32]]!
-               cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *')
-                                                       + (fieldIndex << self shiftForWord)]
-               inSmalltalk: [self flag: #endian.
-                                       fieldIndex = 0
-                                               ifTrue: [bits >> 32]
-                                               ifFalse: [bits bitAnd: 16rFFFFFFFF]]!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitAnd (in category 'common selector sends') -----
  bytecodePrimBitAnd
+       | rcvr arg |
+       arg := self internalStackTop.
+       rcvr := self internalStackValue: 1.
+       ((objectMemory isIntegerObject: arg)
+        and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+               [self internalPop: 2 thenPush: (arg bitAnd: rcvr).
+                ^self fetchNextBytecode "success"].

        self initPrimCall.
        self externalizeIPandSP.
        self primitiveBitAnd.
        self internalizeIPandSP.
+       self successful ifTrue:
+               [^self fetchNextBytecode "success"].
-       self successful ifTrue: [^ self fetchNextBytecode "success"].

        messageSelector := self specialSelector: 14.
        argumentCount := 1.
        self normalSend!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitOr (in category 'common selector sends') -----
  bytecodePrimBitOr
+       | rcvr arg |
+       arg := self internalStackTop.
+       rcvr := self internalStackValue: 1.
+       ((objectMemory isIntegerObject: arg)
+        and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+               [self internalPop: 2 thenPush: (arg bitOr: rcvr).
+                ^self fetchNextBytecode "success"].

        self initPrimCall.
        self externalizeIPandSP.
        self primitiveBitOr.
        self internalizeIPandSP.
+       self successful ifTrue:
+               [^self fetchNextBytecode "success"].
-       self successful ifTrue: [^ self fetchNextBytecode "success"].

        messageSelector := self specialSelector: 15.
        argumentCount := 1.
        self normalSend!


Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1054.mcz

Eliot Miranda-2
 
Hi Nicolas,

On Wed, Feb 11, 2015 at 2:05 PM, Nicolas Cellier <[hidden email]> wrote:
 
If I reformulate:

1) there is a speed-up consisting in bitAnd'ing bitOr'ing the Oop (shifted integer value+tag) directly without need to decode anything when both are immediate SmallInteger

Right.
 
2) this speed-up is already performed in interpreter special bytecode handling and/or in JIT

It wasn't, but it is now.
 
3) so checking again in the primitive is a loss of time

Right.
 
4) the primitive is there just in case the receiver and/or argument is a LargePositiveInteger outside immediate range, but still fitting in an unsigned long (32 or 64 bits)

Not quite.  While in normal execution the primitive will only be called if one or other of the receiver and argument is not a SmallInteger, the primitive will be called whenever the debugger executes bitAnd: or bitXor: since the simulation machinery invokes the primitive, rather than simulating the inlining of the special selectors.

2015-02-11 22:20 GMT+01:00 <[hidden email]>:

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

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

Name: VMMaker.oscog-eem.1054
Author: eem
Time: 11 February 2015, 1:20:01.475 pm
UUID: 3d511797-53fc-4848-b1ec-4b8a1eb0c0ff
Ancestors: VMMaker.oscog-eem.1053

Broaden primitiveBitAnd and primitiveBitOr for Spur
64-bits.  Make the bytecodes handle the common
SmallInteger op SmallInteger case.

Fix C code for and endianness under simulation of
Spur64BitMemoryManager>>fetchLong32:ofFloatObject:

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

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category 'arithmetic integer primitives') -----
  primitiveBitAnd
+       <inline: false>
        | integerReceiver integerArgument |
+       integerArgument := self stackTop.
+       integerReceiver := self stackValue: 1.
+       "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+        ((objectMemory isIntegerObject: integerArgument)
+        and: [objectMemory isIntegerObject: integerReceiver])
+               ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd: integerReceiver)]
+               ifFalse:
+                       ["objectMemory wordSize = 8
+                               ifTrue:
+                                       [integerArgument := self positive64BitValueOf: integerArgument.
+                                        integerReceiver := self positive64BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]
+                               ifFalse:
+                                       [integerArgument := self positive32BitValueOf: integerArgument.
+                                        integerReceiver := self positive32BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]"]"!
-       integerArgument := self popPos32BitInteger.
-       integerReceiver := self popPos32BitInteger.
-       self successful
-               ifTrue: [self push: (self positive32BitIntegerFor:
-                                       (integerReceiver bitAnd: integerArgument))]
-               ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitOr (in category 'arithmetic integer primitives') -----
  primitiveBitOr
+       <inline: false>
        | integerReceiver integerArgument |
+       integerArgument := self stackTop.
+       integerReceiver := self stackValue: 1.
+       "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+        ((objectMemory isIntegerObject: integerArgument)
+        and: [objectMemory isIntegerObject: integerReceiver])
+               ifTrue: [self pop: 2 thenPush: (integerArgument bitOr: integerReceiver)]
+               ifFalse:
+                       ["objectMemory wordSize = 8
+                               ifTrue:
+                                       [integerArgument := self positive64BitValueOf: integerArgument.
+                                        integerReceiver := self positive64BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]
+                               ifFalse:
+                                       [integerArgument := self positive32BitValueOf: integerArgument.
+                                        integerReceiver := self positive32BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitOr: integerReceiver))]]"]"!
-       integerArgument := self popPos32BitInteger.
-       integerReceiver := self popPos32BitInteger.
-       self successful
-               ifTrue: [self push: (self positive32BitIntegerFor:
-                                       (integerReceiver bitOr: integerArgument))]
-               ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') -----
  fetchLong32: fieldIndex ofFloatObject: oop
        "index by word size, and return a pointer as long as the word size"

        | bits |
        (self isImmediateFloat: oop) ifFalse:
                [^self fetchLong32: fieldIndex ofObject: oop].
        bits := self smallFloatBitsOf: oop.
        ^self
+               cCode: [(self cCoerceSimple: (self addressOf: bits) to: #'int *') at: fieldIndex]
+               inSmalltalk:
+                       [self flag: #endian.
+                        fieldIndex = 0
+                               ifTrue: [bits bitAnd: 16rFFFFFFFF]
+                               ifFalse: [bits >> 32]]!
-               cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *')
-                                                       + (fieldIndex << self shiftForWord)]
-               inSmalltalk: [self flag: #endian.
-                                       fieldIndex = 0
-                                               ifTrue: [bits >> 32]
-                                               ifFalse: [bits bitAnd: 16rFFFFFFFF]]!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitAnd (in category 'common selector sends') -----
  bytecodePrimBitAnd
+       | rcvr arg |
+       arg := self internalStackTop.
+       rcvr := self internalStackValue: 1.
+       ((objectMemory isIntegerObject: arg)
+        and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+               [self internalPop: 2 thenPush: (arg bitAnd: rcvr).
+                ^self fetchNextBytecode "success"].

        self initPrimCall.
        self externalizeIPandSP.
        self primitiveBitAnd.
        self internalizeIPandSP.
+       self successful ifTrue:
+               [^self fetchNextBytecode "success"].
-       self successful ifTrue: [^ self fetchNextBytecode "success"].

        messageSelector := self specialSelector: 14.
        argumentCount := 1.
        self normalSend!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitOr (in category 'common selector sends') -----
  bytecodePrimBitOr
+       | rcvr arg |
+       arg := self internalStackTop.
+       rcvr := self internalStackValue: 1.
+       ((objectMemory isIntegerObject: arg)
+        and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+               [self internalPop: 2 thenPush: (arg bitOr: rcvr).
+                ^self fetchNextBytecode "success"].

        self initPrimCall.
        self externalizeIPandSP.
        self primitiveBitOr.
        self internalizeIPandSP.
+       self successful ifTrue:
+               [^self fetchNextBytecode "success"].
-       self successful ifTrue: [^ self fetchNextBytecode "success"].

        messageSelector := self specialSelector: 15.
        argumentCount := 1.
        self normalSend!






--
best,
Eliot
Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1054.mcz

Nicolas Cellier
 


2015-02-11 23:14 GMT+01:00 Eliot Miranda <[hidden email]>:
 
Hi Nicolas,

On Wed, Feb 11, 2015 at 2:05 PM, Nicolas Cellier <[hidden email]> wrote:
 
If I reformulate:

1) there is a speed-up consisting in bitAnd'ing bitOr'ing the Oop (shifted integer value+tag) directly without need to decode anything when both are immediate SmallInteger

Right.
 
2) this speed-up is already performed in interpreter special bytecode handling and/or in JIT

It wasn't, but it is now.
 
3) so checking again in the primitive is a loss of time

Right.
 
4) the primitive is there just in case the receiver and/or argument is a LargePositiveInteger outside immediate range, but still fitting in an unsigned long (32 or 64 bits)

Not quite.  While in normal execution the primitive will only be called if one or other of the receiver and argument is not a SmallInteger, the primitive will be called whenever the debugger executes bitAnd: or bitXor: since the simulation machinery invokes the primitive, rather than simulating the inlining of the special selectors.

OK, it's good to keep this case in mind...
When debugging, I presume we can afford to be a tiny bit slower and allways decode/encode the SmallIntegers.

Note that bitAnd'ing a positive SmallInteger with any LargeInteger (positive or not) will allways answer a SmallInteger...
So we might create another optimization in the primitive for this case...
Or maybe it's too crooked ;)

Similarly, bitAnd'ing a negative SmallInteger with any LargeInteger will never answer a SmallInteger.


2015-02-11 22:20 GMT+01:00 <[hidden email]>:

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

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

Name: VMMaker.oscog-eem.1054
Author: eem
Time: 11 February 2015, 1:20:01.475 pm
UUID: 3d511797-53fc-4848-b1ec-4b8a1eb0c0ff
Ancestors: VMMaker.oscog-eem.1053

Broaden primitiveBitAnd and primitiveBitOr for Spur
64-bits.  Make the bytecodes handle the common
SmallInteger op SmallInteger case.

Fix C code for and endianness under simulation of
Spur64BitMemoryManager>>fetchLong32:ofFloatObject:

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

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitAnd (in category 'arithmetic integer primitives') -----
  primitiveBitAnd
+       <inline: false>
        | integerReceiver integerArgument |
+       integerArgument := self stackTop.
+       integerReceiver := self stackValue: 1.
+       "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+        ((objectMemory isIntegerObject: integerArgument)
+        and: [objectMemory isIntegerObject: integerReceiver])
+               ifTrue: [self pop: 2 thenPush: (integerArgument bitAnd: integerReceiver)]
+               ifFalse:
+                       ["objectMemory wordSize = 8
+                               ifTrue:
+                                       [integerArgument := self positive64BitValueOf: integerArgument.
+                                        integerReceiver := self positive64BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]
+                               ifFalse:
+                                       [integerArgument := self positive32BitValueOf: integerArgument.
+                                        integerReceiver := self positive32BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitAnd: integerReceiver))]]"]"!
-       integerArgument := self popPos32BitInteger.
-       integerReceiver := self popPos32BitInteger.
-       self successful
-               ifTrue: [self push: (self positive32BitIntegerFor:
-                                       (integerReceiver bitAnd: integerArgument))]
-               ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveBitOr (in category 'arithmetic integer primitives') -----
  primitiveBitOr
+       <inline: false>
        | integerReceiver integerArgument |
+       integerArgument := self stackTop.
+       integerReceiver := self stackValue: 1.
+       "Comment out the short-cut.  Either the inline interpreter bytecode or the JIT primitive will handle this case.
+        ((objectMemory isIntegerObject: integerArgument)
+        and: [objectMemory isIntegerObject: integerReceiver])
+               ifTrue: [self pop: 2 thenPush: (integerArgument bitOr: integerReceiver)]
+               ifFalse:
+                       ["objectMemory wordSize = 8
+                               ifTrue:
+                                       [integerArgument := self positive64BitValueOf: integerArgument.
+                                        integerReceiver := self positive64BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive64BitIntegerFor: (integerArgument bitOr: integerReceiver))]]
+                               ifFalse:
+                                       [integerArgument := self positive32BitValueOf: integerArgument.
+                                        integerReceiver := self positive32BitValueOf: integerReceiver.
+                                        self successful ifTrue:
+                                               [self pop: 2 thenPush: (self positive32BitIntegerFor: (integerArgument bitOr: integerReceiver))]]"]"!
-       integerArgument := self popPos32BitInteger.
-       integerReceiver := self popPos32BitInteger.
-       self successful
-               ifTrue: [self push: (self positive32BitIntegerFor:
-                                       (integerReceiver bitOr: integerArgument))]
-               ifFalse: [self unPop: 2]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>fetchLong32:ofFloatObject: (in category 'object access') -----
  fetchLong32: fieldIndex ofFloatObject: oop
        "index by word size, and return a pointer as long as the word size"

        | bits |
        (self isImmediateFloat: oop) ifFalse:
                [^self fetchLong32: fieldIndex ofObject: oop].
        bits := self smallFloatBitsOf: oop.
        ^self
+               cCode: [(self cCoerceSimple: (self addressOf: bits) to: #'int *') at: fieldIndex]
+               inSmalltalk:
+                       [self flag: #endian.
+                        fieldIndex = 0
+                               ifTrue: [bits bitAnd: 16rFFFFFFFF]
+                               ifFalse: [bits >> 32]]!
-               cCode: [self longAt: (self cCoerceSimple: (self addressOf: bits) to: #'char *')
-                                                       + (fieldIndex << self shiftForWord)]
-               inSmalltalk: [self flag: #endian.
-                                       fieldIndex = 0
-                                               ifTrue: [bits >> 32]
-                                               ifFalse: [bits bitAnd: 16rFFFFFFFF]]!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitAnd (in category 'common selector sends') -----
  bytecodePrimBitAnd
+       | rcvr arg |
+       arg := self internalStackTop.
+       rcvr := self internalStackValue: 1.
+       ((objectMemory isIntegerObject: arg)
+        and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+               [self internalPop: 2 thenPush: (arg bitAnd: rcvr).
+                ^self fetchNextBytecode "success"].

        self initPrimCall.
        self externalizeIPandSP.
        self primitiveBitAnd.
        self internalizeIPandSP.
+       self successful ifTrue:
+               [^self fetchNextBytecode "success"].
-       self successful ifTrue: [^ self fetchNextBytecode "success"].

        messageSelector := self specialSelector: 14.
        argumentCount := 1.
        self normalSend!

Item was changed:
  ----- Method: StackInterpreter>>bytecodePrimBitOr (in category 'common selector sends') -----
  bytecodePrimBitOr
+       | rcvr arg |
+       arg := self internalStackTop.
+       rcvr := self internalStackValue: 1.
+       ((objectMemory isIntegerObject: arg)
+        and: [objectMemory isIntegerObject: rcvr]) ifTrue:
+               [self internalPop: 2 thenPush: (arg bitOr: rcvr).
+                ^self fetchNextBytecode "success"].

        self initPrimCall.
        self externalizeIPandSP.
        self primitiveBitOr.
        self internalizeIPandSP.
+       self successful ifTrue:
+               [^self fetchNextBytecode "success"].
-       self successful ifTrue: [^ self fetchNextBytecode "success"].

        messageSelector := self specialSelector: 15.
        argumentCount := 1.
        self normalSend!






--
best,
Eliot


Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1054.mcz

Bert Freudenberg
In reply to this post by Eliot Miranda-2
 
On 11.02.2015, at 23:14, Eliot Miranda <[hidden email]> wrote:

4) the primitive is there just in case the receiver and/or argument is a LargePositiveInteger outside immediate range, but still fitting in an unsigned long (32 or 64 bits)

Not quite.  While in normal execution the primitive will only be called if one or other of the receiver and argument is not a SmallInteger, the primitive will be called whenever the debugger executes bitAnd: or bitXor: since the simulation machinery invokes the primitive, rather than simulating the inlining of the special selectors.

Also, if those selectors are #performed (think proxies etc.), right?

- Bert -




smime.p7s (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-eem.1054.mcz

Eliot Miranda-2
 
Hi Bert,

On Feb 12, 2015, at 1:53 AM, Bert Freudenberg <[hidden email]> wrote:

On 11.02.2015, at 23:14, Eliot Miranda <[hidden email]> wrote:

4) the primitive is there just in case the receiver and/or argument is a LargePositiveInteger outside immediate range, but still fitting in an unsigned long (32 or 64 bits)

Not quite.  While in normal execution the primitive will only be called if one or other of the receiver and argument is not a SmallInteger, the primitive will be called whenever the debugger executes bitAnd: or bitXor: since the simulation machinery invokes the primitive, rather than simulating the inlining of the special selectors.

Also, if those selectors are #performed (think proxies etc.), right?

Oh good point; yes.