Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.866.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.866 Author: eem Time: 27 August 2014, 10:58:56.882 am UUID: 5b1723bd-9d29-4685-be23-7816f5af9822 Ancestors: VMMaker.oscog-eem.865
Define the SmallFloat primitive numbers for 64-bit Spur. Have Slang and the simulators elide primitives that are unimplemented or optional and not selected from the primitive table.
Sista: Fix slip in genBinaryVarOpVarInlinePrimitive: reg alloc.
Implement numSLots in genUnaryInlinePrimitive:.
=============== Diff against VMMaker.oscog-eem.865 ===============
Item was added: + ----- Method: CogObjectRepresentation>>genGetNumSlotsOf:into: (in category 'compile abstract instructions') ----- + genGetNumSlotsOf: srcReg into: destReg + "Get the size in word-sized slots of the object in srcReg into destReg. + srcReg may equal destReg." + self subclassResponsibility!
Item was added: + ----- Method: CogObjectRepresentationFor32BitSpur>>genGetNumSlotsOf:into: (in category 'compile abstract instructions') ----- + genGetNumSlotsOf: srcReg into: destReg + "Get the size in word-sized slots of the object in srcReg into destReg. + srcReg may equal destReg." + <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 MoveR: TempReg R: destReg). + ^0!
Item was changed: ----- Method: SistaStackToRegisterMappingCogit>>ssFlushNoUpdateTo: (in category 'simulation stack') ----- ssFlushNoUpdateTo: index + "This version of ssFlushTo: does /not/ update the simulation stack; it merely generates the spill code. + It is used to spill all values to the stack on a rare failing branch (the class trap) when we don't want to - "This version of ssFlushTo: does /not/ update the simulation stack; it merely h=generates the spill code. - It is used to spill all valiues to teh stack on a rare failing branch (the class trap) when we don't want to flush the stack on the main path and hence mustn't update the simulation stack if there is no spill." <var: 'copiedEntry' type: #CogSimStackEntry> self assert: needsFrame. methodOrBlockNumTemps to: simSpillBase - 1 do: [:i| self assert: (self simStackAt: i) spilled]. simSpillBase <= index ifTrue: [(simSpillBase max: 0) to: index do: [:i| | copiedEntry | copiedEntry := self cCode: [simStack at: index] inSmalltalk: [(simStack at: index) copy]. copiedEntry ensureSpilledAt: (self frameOffsetOfTemporary: i) from: FPReg]]!
Item was changed: ----- Method: StackInterpreter class>>initializePrimitiveTable (in category 'initialization') ----- (excessive size, no diff calculated)
Item was changed: ----- Method: StackInterpreter class>>primitiveAccessorDepthTable (in category 'constants') ----- primitiveAccessorDepthTable | cg | cg := CCodeGenerator new. cg vmClass: StackInterpreter. + ^self primitiveTable collect: - ^PrimitiveTable collect: [:thing| |class method | (thing isInteger "quick prims, 0 for fast primitve fail" or: [thing == #primitiveFail or: [(class := self primitivesClass whichClassIncludesSelector: thing) isNil]]) ifTrue: [-1] ifFalse: [method := (class >> thing) methodNode asTranslationMethodOfClass: TMethod. cg accessorDepthForMethod: method]]!
Item was changed: ----- Method: StackInterpreter class>>primitiveTable (in category 'constants') ----- primitiveTable + | cg | + cg := CCodeGenerator new. + cg vmClass: StackInterpreter. + ^PrimitiveTable collect: + [:thing| + (thing isInteger "quick prims, 0 for fast primitve fail" + or: [thing == #primitiveFail]) + ifTrue: [thing] + ifFalse: + [(self primitivesClass whichClassIncludesSelector: thing) + ifNil: [#primitiveFail] + ifNotNil: + [:class| + (cg shouldIncludeMethodFor: class selector: thing) + ifTrue: [thing] + ifFalse: [#primitiveFail]]]]! - - ^ PrimitiveTable!
Item was changed: ----- Method: StackInterpreter>>tryLoadNewPlugin:pluginEntries: (in category 'primitive support') ----- tryLoadNewPlugin: pluginString pluginEntries: pluginEntries "Load the plugin and if on Spur, populate pluginEntries with the prmitives in the plugin." <doNotGenerate> | plugin realPluginClass plugins simulatorClasses | self transcript cr; show: 'Looking for module ', pluginString. "Defeat loading of the FloatArrayPlugin & Matrix2x3Plugin since complications with 32-bit float support prevent simulation. If you feel up to tackling this start by implementing cCoerce: value to: cType ^cType = 'float' ifTrue: [value asIEEE32BitWord] ifFalse: [value] in FloatArrayPlugin & Matrix2x3Plugin and then address the issues in the BalloonEnginePlugin. See http://forum.world.st/Simulating-the-BalloonEnginePlugin-FloatArrayPlugin-am..." (#('FloatArrayPlugin' 'Matrix2x3Plugin') includes: pluginString) ifTrue: [self transcript show: ' ... defeated'. ^nil]. pluginString isEmpty ifTrue: [plugin := self] ifFalse: [plugins := InterpreterPlugin allSubclasses select: [:psc| psc moduleName asString = pluginString asString]. simulatorClasses := (plugins select: [:psc| psc simulatorClass notNil] thenCollect: [:psc| psc simulatorClass]) asSet. simulatorClasses isEmpty ifTrue: [self transcript show: ' ... not found'. ^nil]. simulatorClasses size > 1 ifTrue: [^self error: 'This won''t work...']. plugins size > 1 ifTrue: [self transcript show: '...multiple plugin classes; choosing ', plugins last name]. realPluginClass := plugins last. "hopefully lowest in the hierarchy..." plugin := simulatorClasses anyOne newFor: realPluginClass. plugin setInterpreter: objectMemory. "Ignore return value from setInterpreter" (plugin respondsTo: #initialiseModule) ifTrue: [plugin initialiseModule ifFalse: [self transcript show: ' ... initialiser failed'. ^nil]]]. "module initialiser failed" self transcript show: ' ... loaded'. objectMemory hasSpurMemoryManagerAPI ifTrue: [| realPlugin cg | self transcript show: '...computing accessor depths'. plugin class isPluginClass ifTrue: [realPlugin := (plugin isSmartSyntaxPluginSimulator ifTrue: [realPluginClass] ifFalse: [plugin class]) withAllSuperclasses detect: [:class| class shouldBeTranslated]. cg := realPlugin buildCodeGeneratorUpTo: realPlugin] ifFalse: [cg := self codeGeneratorToComputeAccessorDepth. primitiveTable withIndexDo: [:prim :index| | depth | prim isSymbol ifTrue: [depth := cg accessorDepthForSelector: prim. + self assert: (depth isInteger or: [depth isNil and: [(plugin class whichClassIncludesSelector: prim) isNil]]). - self assert: depth isInteger. primitiveAccessorDepthTable at: index - 1 put: depth]]]. cg exportedPrimitiveNames do: [:primName| | fnSymbol | fnSymbol := primName asSymbol. pluginEntries addLast: {plugin. fnSymbol. [plugin perform: fnSymbol. self]. cg accessorDepthForSelector: fnSymbol}]. self transcript show: '...done']. ^pluginString asString -> plugin!
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>>#inlinePrimitiveBytecode:" | 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)]. - [self ssAllocateRequiredReg: (rr := 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].
"16 through 19, bitAnd:, bitOr:, bitXor, bitShift:, SmallInteger op SmallInteger => SmallInteger, no overflow"
"32 through 37, >, <, >=, <=. =, ~=, SmallInteger op SmallInteger => Boolean (flags?? then in jump bytecodes if ssTop is a flags value, just generate the instruction!!!!)"
"64 through 68, Pointer Object>>at:, Byte Object>>at:, Short16 Word Object>>at: LongWord32 Object>>at: Quad64Word Object>>at:. obj op 0-rel SmallInteger => oop"
"80 through 84, Pointer Object>>at:put:, Byte Object>>at:put:, Short16 Word Object>>at:put: LongWord32 Object>>at:put: Quad64Word Object>>at:put:. obj op 0-rel SmallInteger => oop"
} otherwise: [^EncounteredUnknownBytecode]. self ssPushRegister: rr. ^0!
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>>#inlinePrimitiveBytecode:" + | 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]. + } + otherwise: + [^EncounteredUnknownBytecode]. + ^0! - "not yet implemented" - ^EncounteredUnknownBytecode!
Item was added: + ----- Method: StackToRegisterMappingCogit>>ssFlushUpThroughRegister: (in category 'simulation stack') ----- + ssFlushUpThroughRegister: reg + "Any occurrences on the stack of the register must be + flushed, and hence any values colder than them stack." + <var: #desc type: #'CogSimStackEntry *'> + simStackPtr - 1 to: (simSpillBase max: 0) by: -1 do: + [:index| | desc | + desc := self simStackAt: index. + (desc type = SSRegister + and: [desc register = reg]) ifTrue: + [self ssFlushTo: index. + ^self]]!
vm-dev@lists.squeakfoundation.org