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! |
Free forum by Nabble | Edit this page |