Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1509.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1509 Author: eem Time: 4 November 2015, 11:28:10.971 am UUID: f6a1e16a-fc26-4558-b806-cff0653e30a2 Ancestors: VMMaker.oscog-eem.1508
x64 Cogit: Streamline genInnerPrimitiveIdentityHash: to compute the tag pattern only once.
Fix shifting by > 31 bits.
Fix in-image compilation of same.
Fix the simulation assert checking valid jump targets.
=============== Diff against VMMaker.oscog-eem.1508 ===============
Item was changed: ----- Method: CogAbstractInstruction>>jmpTarget: (in category 'accessing') ----- jmpTarget: anAbstractInstruction "Set the target of a jump instruction. These all have the target in the first operand." <returnTypeC: #'AbstractInstruction *'> <var: #anAbstractInstruction type: #'AbstractInstruction *'> self cCode: [] "check for inadvertent smashing of already-set jmpTargets; development only" inSmalltalk: [self assert: ((operands at: 0) ifNil: [true] + ifNotNil: [:o| + o = 0 + or: [(self isAFixup: o) + or: [self isAnInstruction: anAbstractInstruction]]])]. - ifNotNil: [:o| o = 0 or: [self isAFixup: o]])]. operands at: 0 put: anAbstractInstruction asUnsignedInteger. ^anAbstractInstruction!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genConvertCharacterToSmallIntegerInReg: (in category 'compile abstract instructions') ----- + genConvertCharacterToSmallIntegerInReg: reg + "Convert the SmallInteger in reg to a Character, assuming + the SmallInteger's value is a valid character." + cogit SubCq: objectMemory characterTag - objectMemory smallIntegerTag R: reg!
Item was changed: ----- Method: CogObjectRepresentationFor64BitSpur>>genGetHashFieldNonImmOf:asSmallIntegerInto: (in category 'compile abstract instructions') ----- genGetHashFieldNonImmOf: instReg asSmallIntegerInto: destReg "Fetch the instance's identity hash into destReg, encoded as a SmallInteger." + cogit + MoveMw: 0 r: instReg R: destReg; + "Shift and mask the field leaving room for the SmallInteger tag." + LogicalShiftRightCq: objectMemory identityHashFullWordShift - objectMemory numTagBits R: destReg; + AndCq: objectMemory identityHashHalfWordMask << objectMemory numTagBits R: destReg; + AddCq: objectMemory smallIntegerTag R: destReg. - "Get header word in scratchReg" - cogit MoveMw: 0 r: instReg R: destReg. - "Shift and mask the field leaving room for the SmallInteger tag." - cogit LogicalShiftRightCq: objectMemory identityHashFullWordShift R: destReg. - cogit AndCq: objectMemory identityHashHalfWordMask R: destReg. - self genConvertIntegerToSmallIntegerInReg: destReg. ^0!
Item was changed: ----- Method: CogObjectRepresentationFor64BitSpur>>genInnerPrimitiveIdentityHash: (in category 'primitive generators') ----- genInnerPrimitiveIdentityHash: retNoffset + | jumpImm jumpSF jumpNotSet ret | - | jumpImm jumpSI jumpSF jumpNotSet ret | - <var: #jumpSI type: #'AbstractInstruction *'> <var: #jumpSF type: #'AbstractInstruction *'> <var: #jumpImm type: #'AbstractInstruction *'> <var: #jumpNotSet type: #'AbstractInstruction *'> + jumpImm := self genJumpImmediate: ReceiverResultReg. "uses TstCqR" - jumpImm := self genJumpImmediate: ReceiverResultReg. self genGetHashFieldNonImmOf: ReceiverResultReg asSmallIntegerInto: TempReg. cogit CmpCq: ConstZero R: TempReg. jumpNotSet := cogit JumpZero: 0. cogit MoveR: TempReg R: ReceiverResultReg. ret := cogit RetN: retNoffset. jumpImm jmpTarget: cogit Label. + jumpSF := cogit "Fail SmallFloat because their hash uses rotatedFloatBitsOf: the oop" + AndCq: objectMemory tagMask R: ReceiverResultReg R: TempReg; + CmpCq: objectMemory smallIntegerTag R: TempReg; + JumpZero: ret; + CmpCq: objectMemory characterTag R: TempReg; + JumpNonZero: 0. - jumpSI := self genJumpSmallInteger: ReceiverResultReg. - jumpSI asInteger = UnimplementedOperation ifTrue: - [cogit MoveR: ReceiverResultReg R: TempReg. - jumpSI := self genJumpSmallIntegerInScratchReg: TempReg]. - jumpSI jmpTarget: ret. - "Fail SmallFloat because their hash uses rotatedFloatBitsOf: the oop" - jumpSF := self genJumpSmallFloat: ReceiverResultReg. - jumpSF asInteger = UnimplementedOperation ifTrue: - [cogit MoveR: ReceiverResultReg R: TempReg. - jumpSI := self genJumpSmallFloatInScratchReg: TempReg]. self genConvertCharacterToSmallIntegerInReg: ReceiverResultReg. cogit Jump: ret. jumpNotSet jmpTarget: (jumpSF jmpTarget: cogit Label). ^0!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genJumpNotSmallFloat:scratchReg: (in category 'compile abstract instructions') ----- + genJumpNotSmallFloat: reg scratchReg: scratch + "Generate a compare and branch to test if aRegister contains other than a SmallFloat. + Answer the jump." + cogit AndCq: objectMemory tagMask R: reg R: scratch. + cogit CmpCq: objectMemory smallFloatTag R: scratch. + ^cogit JumpNonZero: 0!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genJumpNotSmallFloatInScratchReg: (in category 'compile abstract instructions') ----- + genJumpNotSmallFloatInScratchReg: aRegister + ^self genJumpNotSmallFloat: aRegister scratchReg: TempReg!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genJumpSmallFloat: (in category 'compile abstract instructions') ----- + genJumpSmallFloat: aRegister + "Generate a compare and branch to test if aRegister contains a SmallFloat. + Answer the jump, or UnimplementedOperation if this cannot be done with + a single register." + <returnTypeC: #'AbstractInstruction *'> + <inline: true> + ^cogit cCoerceSimple: UnimplementedOperation to: #'AbstractInstruction *'!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genJumpSmallFloat:scratchReg: (in category 'compile abstract instructions') ----- + genJumpSmallFloat: reg scratchReg: scratch + "Generate a compare and branch to test if aRegister contains a SmallFloat. + Answer the jump. Override since scratch is needed." + cogit AndCq: objectMemory tagMask R: reg R: scratch. + cogit CmpCq: objectMemory smallFloatTag R: scratch. + ^cogit JumpZero: 0!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genJumpSmallFloatInScratchReg: (in category 'compile abstract instructions') ----- + genJumpSmallFloatInScratchReg: aRegister + ^self genJumpSmallFloat: aRegister scratchReg: TempReg!
Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genJumpSmallIntegerInScratchReg: (in category 'compile abstract instructions') ----- + genJumpSmallIntegerInScratchReg: aRegister + ^self genJumpSmallInteger: aRegister scratchReg: TempReg!
Item was changed: ----- Method: CogX64Compiler>>computeMaximumSize (in category 'generate machine code') ----- computeMaximumSize "Compute the maximum size for each opcode. This allows jump offsets to be determined, provided that all backward branches are long branches." "N.B. The ^N forms are to get around the bytecode compiler's long branch limits which are exceeded when each case jumps around the otherwise." opcode caseOf: { "Noops & Pseudo Ops" [Label] -> [^0]. [AlignmentNops] -> [^(operands at: 0) - 1]. [Fill16] -> [^2]. [Fill32] -> [^4]. [FillFromWord] -> [^4]. [Nop] -> [^1]. "Specific Control/Data Movement" [CDQ] -> [^2]. [IDIVR] -> [^3]. [IMULRR] -> [^4]. [CPUID] -> [^2]. [CMPXCHGAwR] -> [^8]. [CMPXCHGMwrR] -> [^9]. [LFENCE] -> [^3]. [MFENCE] -> [^3]. [SFENCE] -> [^3]. [LOCK] -> [^1]. "[XCHGAwR] -> [^6]. [XCHGMwrR] -> [^7]." [XCHGRR] -> [^((self concreteRegister: (operands at: 0)) = RAX or: [(self concreteRegister: (operands at: 1)) = RAX]) ifTrue: [2] ifFalse: [3]]. "Control" [CallFull] -> [^12]. [Call] -> [^5]. [JumpR] -> [^2]. [JumpFull] -> [self resolveJumpTarget. ^12]. [JumpLong] -> [self resolveJumpTarget. ^5]. [Jump] -> [self resolveJumpTarget. ^5]. [JumpZero] -> [self resolveJumpTarget. ^6]. [JumpNonZero] -> [self resolveJumpTarget. ^6]. [JumpNegative] -> [self resolveJumpTarget. ^6]. [JumpNonNegative] -> [self resolveJumpTarget. ^6]. [JumpOverflow] -> [self resolveJumpTarget. ^6]. [JumpNoOverflow] -> [self resolveJumpTarget. ^6]. [JumpCarry] -> [self resolveJumpTarget. ^6]. [JumpNoCarry] -> [self resolveJumpTarget. ^6]. [JumpLess] -> [self resolveJumpTarget. ^6]. [JumpGreaterOrEqual] -> [self resolveJumpTarget. ^6]. [JumpGreater] -> [self resolveJumpTarget. ^6]. [JumpLessOrEqual] -> [self resolveJumpTarget. ^6]. [JumpBelow] -> [self resolveJumpTarget. ^6]. [JumpAboveOrEqual] -> [self resolveJumpTarget. ^6]. [JumpAbove] -> [self resolveJumpTarget. ^6]. [JumpBelowOrEqual] -> [self resolveJumpTarget. ^6]. [JumpLongZero] -> [self resolveJumpTarget. ^6]. [JumpLongNonZero] -> [self resolveJumpTarget. ^6]. [JumpFPEqual] -> [self resolveJumpTarget. ^6]. [JumpFPNotEqual] -> [self resolveJumpTarget. ^6]. [JumpFPLess] -> [self resolveJumpTarget. ^6]. [JumpFPGreaterOrEqual] -> [self resolveJumpTarget. ^6]. [JumpFPGreater] -> [self resolveJumpTarget. ^6]. [JumpFPLessOrEqual] -> [self resolveJumpTarget. ^6]. [JumpFPOrdered] -> [self resolveJumpTarget. ^6]. [JumpFPUnordered] -> [self resolveJumpTarget. ^6]. [RetN] -> [^(operands at: 0) = 0 ifTrue: [1] ifFalse: [3]]. [Stop] -> [^1].
"Arithmetic" [AddCqR] -> [^self computeSizeOfArithCqR]. [AndCqR] -> [^self computeSizeOfArithCqR]. [CmpCqR] -> [^self computeSizeOfArithCqR]. [OrCqR] -> [^self computeSizeOfArithCqR]. [SubCqR] -> [^self computeSizeOfArithCqR]. [TstCqR] -> [^self computeSizeOfArithCqR]. [AddCwR] -> [^self computeSizeOfArithCwR]. [AndCwR] -> [^self computeSizeOfArithCwR]. [CmpCwR] -> [^self computeSizeOfArithCwR]. [OrCwR] -> [^self computeSizeOfArithCwR]. [SubCwR] -> [^self computeSizeOfArithCwR]. [XorCwR] -> [^self computeSizeOfArithCwR]. [AddRR] -> [^3]. [AndRR] -> [^3]. [CmpRR] -> [^3]. [OrRR] -> [^3]. [XorRR] -> [^3]. [SubRR] -> [^3]. [NegateR] -> [^3]. [LoadEffectiveAddressMwrR] -> [^((self isQuick: (operands at: 0)) ifTrue: [4] ifFalse: [7]) + (((self concreteRegister: (operands at: 1)) bitAnd: 7) = RSP ifTrue: [1] ifFalse: [0])]. + [LogicalShiftLeftCqR] -> [^self computeShiftCqRegSize]. + [LogicalShiftRightCqR] -> [^self computeShiftCqRegSize]. + [ArithmeticShiftRightCqR] -> [^self computeShiftCqRegSize]. - [LogicalShiftLeftCqR] -> [^(operands at: 0) = 1 ifTrue: [3] ifFalse: [4]]. - [LogicalShiftRightCqR] -> [^(operands at: 0) = 1 ifTrue: [3] ifFalse: [4]]. - [ArithmeticShiftRightCqR] -> [^(operands at: 0) = 1 ifTrue: [3] ifFalse: [4]]. [LogicalShiftLeftRR] -> [^self computeShiftRRSize]. [LogicalShiftRightRR] -> [^self computeShiftRRSize]. [ArithmeticShiftRightRR] -> [^self computeShiftRRSize]. [AddRdRd] -> [^4]. [CmpRdRd] -> [^4]. [SubRdRd] -> [^4]. [MulRdRd] -> [^4]. [DivRdRd] -> [^4]. [SqrtRd] -> [^4]. "Data Movement" [MoveCqR] -> [^(operands at: 0) = 0 ifTrue: [3] ifFalse: [(self is32BitSignedImmediate: (operands at: 0)) ifTrue: [7] ifFalse: [self moveCwRByteSize]]]. [MoveCwR] -> [^(self inCurrentCompilation: (operands at: 0)) ifTrue: [7] ifFalse: [self moveCwRByteSize]]. [MoveC32R] -> [^7]. "N.B. Always inlined." [MoveRR] -> [^3]. [MoveRdRd] -> [^4]. [MoveAwR] -> [^(self isAddressRelativeToVarBase: (operands at: 0)) ifTrue: [7] ifFalse: [(self concreteRegister: (operands at: 1)) = RAX ifTrue: [10] ifFalse: [14]]]. [MoveRAw] -> [^(self isAddressRelativeToVarBase: (operands at: 1)) ifTrue: [7] ifFalse: [(self concreteRegister: (operands at: 0)) = RAX ifTrue: [10] ifFalse: [14]]]. [MoveAbR] -> [^(self isAddressRelativeToVarBase: (operands at: 0)) ifTrue: [7] ifFalse: [(self concreteRegister: (operands at: 1)) = RAX ifTrue: [10] ifFalse: [14]]]. [MoveRAb] -> [^(self isAddressRelativeToVarBase: (operands at: 1)) ifTrue: [7] ifFalse: [(self concreteRegister: (operands at: 0)) = RAX ifTrue: [10] ifFalse: [14]]]. [MoveRMwr] -> [self assert: (self is32BitSignedImmediate: (operands at: 1)). ^((self isQuick: (operands at: 1)) ifTrue: [((operands at: 1) = 0 and: [((self concreteRegister: (operands at: 2)) bitAnd: 7) ~= RBP]) ifTrue: [3] ifFalse: [4]] ifFalse: [7]) + (((self concreteRegister: (operands at: 2)) bitAnd: 7) = RSP ifTrue: [1] ifFalse: [0])]. "[MoveRdM64r] -> [^((self isQuick: (operands at: 1)) ifTrue: [5] ifFalse: [8]) + ((self concreteRegister: (operands at: 2)) = ESP ifTrue: [1] ifFalse: [0])]." [MoveMbrR] -> [self assert: (self is32BitSignedImmediate: (operands at: 0)). ^((self isQuick: (operands at: 0)) ifTrue: [((operands at: 0) = 0 and: [((self concreteRegister: (operands at: 1)) bitAnd: 7) ~= RBP]) ifTrue: [3] ifFalse: [4]] ifFalse: [7]) + (((self concreteRegister: (operands at: 1)) bitAnd: 7) = RSP ifTrue: [1] ifFalse: [0])]. [MoveRMbr] -> [self assert: (self is32BitSignedImmediate: (operands at: 1)). ^((self isQuick: (operands at: 1)) ifTrue: [((operands at: 1) = 0 and: [((self concreteRegister: (operands at: 0)) bitAnd: 7) ~= RBP]) ifTrue: [3] ifFalse: [4]] ifFalse: [7]) + (((self concreteRegister: (operands at: 2)) bitAnd: 7) = RSP ifTrue: [1] ifFalse: [0])]. [MoveM16rR] -> [^((self isQuick: (operands at: 0)) ifTrue: [((operands at: 0) = 0 and: [((self concreteRegister: (operands at: 1)) bitAnd: 7) ~= RBP]) ifTrue: [4] ifFalse: [5]] ifFalse: [8]) + (((self concreteRegister: (operands at: 1)) bitAnd: 7) = RSP ifTrue: [1] ifFalse: [0])]. "[MoveM64rRd] -> [^((self isQuick: (operands at: 0)) ifTrue: [5] ifFalse: [8]) + ((self concreteRegister: (operands at: 1)) = ESP ifTrue: [1] ifFalse: [0])]." [MoveMwrR] -> [self assert: (self is32BitSignedImmediate: (operands at: 0)). ^((self isQuick: (operands at: 0)) ifTrue: [((operands at: 0) = 0 and: [((self concreteRegister: (operands at: 1)) bitAnd: 7) ~= RBP]) ifTrue: [3] ifFalse: [4]] ifFalse: [7]) + (((self concreteRegister: (operands at: 1)) bitAnd: 7) = RSP ifTrue: [1] ifFalse: [0])]. [MoveXbrRR] -> [self assert: (self concreteRegister: (operands at: 0)) ~= RSP. ^((self concreteRegister: (operands at: 1)) bitAnd: 7) = RBP ifTrue: [5] ifFalse: [4]]. [MoveRXbrR] -> [self assert: (self concreteRegister: (operands at: 1)) ~= RSP. ^(((self concreteRegister: (operands at: 0)) < 8 and: [(self concreteRegister: (operands at: 1)) < 8 and: [(self concreteRegister: (operands at: 2)) < 8]]) ifTrue: [3] ifFalse: [4]) + (((self concreteRegister: (operands at: 2)) bitAnd: 7) = RBP ifTrue: [1] ifFalse: [0])]. [MoveXwrRR] -> [self assert: (self concreteRegister: (operands at: 0)) ~= RSP. ^((self concreteRegister: (operands at: 1)) = RBP or: [(self concreteRegister: (operands at: 1)) = R13]) ifTrue: [5] ifFalse: [4]]. [MoveRXwrR] -> [self assert: (self concreteRegister: (operands at: 1)) ~= RSP. ^((self concreteRegister: (operands at: 2)) = RBP or: [(self concreteRegister: (operands at: 2)) = R13]) ifTrue: [5] ifFalse: [4]]. [PopR] -> [^(self concreteRegister: (operands at: 0)) < 8 ifTrue: [1] ifFalse: [2]]. [PushR] -> [^(self concreteRegister: (operands at: 0)) < 8 ifTrue: [1] ifFalse: [2]]. [PushCq] -> [^(self isQuick: (operands at: 0)) ifTrue: [2] ifFalse: [5]]. [PushCw] -> [^(self inCurrentCompilation: (operands at: 0)) ifTrue: [9] ifFalse: [self pushCwByteSize]]. [PrefetchAw] -> [^(self isAddressRelativeToVarBase: (operands at: 0)) ifTrue: [7] ifFalse: [0]]. "Conversion" "[ConvertRRd] -> [^4]" }. ^0 "to keep C compiler quiet"!
Item was added: + ----- Method: CogX64Compiler>>computeShiftCqRegSize (in category 'generate machine code') ----- + computeShiftCqRegSize + "Immediate shifts are limited to a maximum of 31." + <inline: true> + | distance | + distance := operands at: 0. + distance = 1 ifTrue: + [^3]. + distance <= 31 ifTrue: + [^4]. + distance = 32 ifTrue: + [^7]. + ^8!
Item was changed: ----- Method: CogX64Compiler>>concretizeShiftCqRegOpcode: (in category 'generate machine code') ----- concretizeShiftCqRegOpcode: regOpcode "Will get inlined into concretizeAt: switch." <inline: true> | distance reg | + distance := operands at: 0. + self assert: (distance between: 1 and: 63). - distance := (operands at: 0) min: 31. reg := self concreteRegister: (operands at: 1). machineCode at: 0 put: (self rexR: 0 x: 0 b: reg). distance = 1 ifTrue: [machineCode at: 1 put: 16rD1; at: 2 put: (self mod: ModReg RM: reg RO: regOpcode). ^machineCodeSize := 3]. machineCode at: 1 put: 16rC1; at: 2 put: (self mod: ModReg RM: reg RO: regOpcode); + at: 3 put: (distance min: 31). + distance <= 31 ifTrue: + [^machineCodeSize := 4]. + distance = 32 ifTrue: + [machineCode + at: 4 put: 16rD1; + at: 5 put: (self mod: ModReg RM: reg RO: regOpcode). + ^machineCodeSize := 7]. + machineCode + at: 4 put: 16rC1; + at: 5 put: (self mod: ModReg RM: reg RO: regOpcode); + at: 6 put: distance - 31. + ^machineCodeSize := 8! - at: 3 put: distance. - ^machineCodeSize := 4!
Item was added: + ----- Method: CurrentImageCoInterpreterFacadeFor64BitSpurObjectRepresentation>>smallFloatTag (in category 'accessing') ----- + smallFloatTag + ^objectMemory smallFloatTag!
Item was added: + ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>identityHashFullWordShift (in category 'accessing') ----- + identityHashFullWordShift + ^objectMemory identityHashFullWordShift!
Item was added: + ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>numTagBits (in category 'accessing') ----- + numTagBits + ^objectMemory numTagBits!
vm-dev@lists.squeakfoundation.org