VM Maker: VMMaker.oscog-cb.993.mcz

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

VM Maker: VMMaker.oscog-cb.993.mcz

commits-2
 
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!