[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