[Vm-dev] VM Maker: VMMaker.oscog-eem.1509.mcz
commits at source.squeak.org
commits at source.squeak.org
Wed Nov 4 19:30:00 UTC 2015
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!
More information about the Vm-dev
mailing list