Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2638.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2638 Author: eem Time: 26 December 2019, 10:02:05.572892 pm UUID: ab76ca48-4c80-4fe7-964a-047389ca5746 Ancestors: VMMaker.oscog-eem.2637 Use three argument shifts to save an instruction in converting teh result of a division primitive into a SmallInteger. (We can do the same for the set tags case too, but have toi introduce OrCqRR or similar). =============== Diff against VMMaker.oscog-eem.2637 =============== Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveDiv (in category 'primitive generators') ----- genPrimitiveDiv | jumpNotSI jumpIsSI jumpZero jumpExact jumpSameSign convert | <var: #convert type: #'AbstractInstruction *'> <var: #jumpIsSI type: #'AbstractInstruction *'> <var: #jumpZero type: #'AbstractInstruction *'> <var: #jumpNotSI type: #'AbstractInstruction *'> <var: #jumpExact type: #'AbstractInstruction *'> <var: #jumpSameSign type: #'AbstractInstruction *'> cogit processorHasDivQuoRemAndMClassIsSmallInteger ifFalse: [^UnimplementedPrimitive]. cogit genLoadArgAtDepth: 0 into: Arg0Reg. cogit MoveR: Arg0Reg R: ClassReg. cogit MoveR: Arg0Reg R: Arg1Reg. jumpNotSI := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg. "We must shift away the tags, not just subtract them, so that the overflow case doesn't actually overflow the machine instruction." self genShiftAwaySmallIntegerTagsInScratchReg: ClassReg. (cogit lastOpcode setsConditionCodesFor: JumpZero) ifFalse: [cogit CmpCq: 0 R: ClassReg]. jumpZero := cogit JumpZero: 0. cogit MoveR: ReceiverResultReg R: TempReg. self genShiftAwaySmallIntegerTagsInScratchReg: TempReg. cogit DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg. "If remainder is zero we must check for overflow." cogit CmpCq: 0 R: ClassReg. jumpExact := cogit JumpZero: 0. "If arg and remainder signs are different we must round down." cogit XorR: ClassReg R: Arg1Reg. (cogit lastOpcode setsConditionCodesFor: JumpZero) ifFalse: [cogit CmpCq: 0 R: Arg1Reg]. jumpSameSign := cogit JumpGreaterOrEqual: 0. cogit SubCq: 1 R: TempReg. jumpSameSign jmpTarget: (convert := cogit Label). + self genConvertIntegerInReg: TempReg toSmallIntegerInReg: ReceiverResultReg. - self genConvertIntegerToSmallIntegerInReg: TempReg. - cogit MoveR: TempReg R: ReceiverResultReg. cogit genPrimReturn. "test for overflow; the only case is SmallInteger minVal // -1" jumpExact jmpTarget: cogit Label. jumpIsSI := self genJumpIsSmallIntegerValue: TempReg scratch: Arg1Reg. jumpIsSI jmpTarget: convert. jumpZero jmpTarget: (jumpNotSI jmpTarget: cogit Label). ^CompletePrimitive! Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveDivide (in category 'primitive generators') ----- genPrimitiveDivide | jumpNotSI jumpZero jumpInexact jumpOverflow | <var: #jumpNotSI type: #'AbstractInstruction *'> <var: #jumpZero type: #'AbstractInstruction *'> <var: #jumpInexact type: #'AbstractInstruction *'> <var: #jumpOverflow type: #'AbstractInstruction *'> cogit processorHasDivQuoRemAndMClassIsSmallInteger ifFalse: [^UnimplementedPrimitive]. cogit genLoadArgAtDepth: 0 into: Arg0Reg. cogit MoveR: Arg0Reg R: ClassReg. jumpNotSI := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg. "We must shift away the tags, not just subtract them, so that the overflow case doesn't actually overflow the machine instruction." self genShiftAwaySmallIntegerTagsInScratchReg: ClassReg. jumpZero := cogit JumpZero: 0. cogit MoveR: ReceiverResultReg R: TempReg. self genShiftAwaySmallIntegerTagsInScratchReg: TempReg. cogit DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg. "If remainder is non-zero fail." cogit CmpCq: 0 R: ClassReg. jumpInexact := cogit JumpNonZero: 0. "test for overflow; the only case is SmallInteger minVal / -1" jumpOverflow := self genJumpNotSmallIntegerValue: TempReg scratch: Arg1Reg. + self genConvertIntegerInReg: TempReg toSmallIntegerInReg: ReceiverResultReg. - self genConvertIntegerToSmallIntegerInReg: TempReg. - cogit MoveR: TempReg R: ReceiverResultReg. cogit genPrimReturn. jumpOverflow jmpTarget: (jumpInexact jmpTarget: (jumpZero jmpTarget: (jumpNotSI jmpTarget: cogit Label))). ^CompletePrimitive! Item was changed: ----- Method: CogObjectRepresentation>>genPrimitiveQuo (in category 'primitive generators') ----- genPrimitiveQuo | convert jumpNotSI jumpZero jumpIsSI jumpExact | <var: #convert type: #'AbstractInstruction *'> <var: #jumpIsSI type: #'AbstractInstruction *'> <var: #jumpZero type: #'AbstractInstruction *'> <var: #jumpNotSI type: #'AbstractInstruction *'> <var: #jumpExact type: #'AbstractInstruction *'> cogit processorHasDivQuoRemAndMClassIsSmallInteger ifFalse: [^UnimplementedPrimitive]. cogit genLoadArgAtDepth: 0 into: Arg0Reg. cogit MoveR: Arg0Reg R: ClassReg. jumpNotSI := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg. "We must shift away the tags, not just subtract them, so that the overflow case doesn't actually overflow the machine instruction." self genShiftAwaySmallIntegerTagsInScratchReg: ClassReg. (cogit lastOpcode setsConditionCodesFor: JumpZero) ifFalse: [cogit CmpCq: 0 R: ClassReg]. jumpZero := cogit JumpZero: 0. cogit MoveR: ReceiverResultReg R: TempReg. self genShiftAwaySmallIntegerTagsInScratchReg: TempReg. cogit DivR: ClassReg R: TempReg Quo: TempReg Rem: ClassReg. "If remainder is zero we must check for overflow." cogit CmpCq: 0 R: ClassReg. jumpExact := cogit JumpZero: 0. convert := cogit Label. + self genConvertIntegerInReg: TempReg toSmallIntegerInReg: ReceiverResultReg. - self genConvertIntegerToSmallIntegerInReg: TempReg. - cogit MoveR: TempReg R: ReceiverResultReg. cogit genPrimReturn. jumpExact jmpTarget: cogit Label. jumpIsSI := self genJumpIsSmallIntegerValue: TempReg scratch: Arg1Reg. jumpIsSI jmpTarget: convert. jumpZero jmpTarget: (jumpNotSI jmpTarget: cogit Label). ^CompletePrimitive! Item was added: + ----- Method: CogObjectRepresentationFor32BitSpur>>genConvertIntegerInReg:toSmallIntegerInReg: (in category 'compile abstract instructions') ----- + genConvertIntegerInReg: srcReg toSmallIntegerInReg: destReg + cogit LogicalShiftLeftCq: 1 R: srcReg R: destReg. + cogit AddCq: 1 R: destReg. + ^0! Item was added: + ----- Method: CogObjectRepresentationFor64BitSpur>>genConvertIntegerInReg:toSmallIntegerInReg: (in category 'compile abstract instructions') ----- + genConvertIntegerInReg: srcReg toSmallIntegerInReg: destReg + cogit LogicalShiftLeftCq: objectMemory numTagBits R: srcReg R: destReg. + cogit AddCq: 1 R: destReg. + ^0! Item was changed: ----- Method: CogObjectRepresentationForSpur>>genPrimitiveSize (in category 'primitive generators') ----- genPrimitiveSize | jumpImm jumpNotIndexable jumpIsContext | "c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:" <var: #jumpImm type: #'AbstractInstruction *'> <var: #jumpIsContext type: #'AbstractInstruction *'> <var: #jumpNotIndexable type: #'AbstractInstruction *'> jumpImm := self genJumpImmediate: ReceiverResultReg. self genGetSizeOf: ReceiverResultReg into: ClassReg formatReg: SendNumArgsReg scratchReg: TempReg abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic]. + self genConvertIntegerInReg: ClassReg toSmallIntegerInReg: ReceiverResultReg. - self genConvertIntegerToSmallIntegerInReg: ClassReg. - cogit MoveR: ClassReg R: ReceiverResultReg. cogit genPrimReturn. jumpImm jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)). ^CompletePrimitive! Item was added: + ----- Method: CogObjectRepresentationForSqueakV3>>genConvertIntegerInReg:toSmallIntegerInReg: (in category 'compile abstract instructions') ----- + genConvertIntegerInReg: srcReg toSmallIntegerInReg: destReg + cogit LogicalShiftLeftCq: 1 R: srcReg R: destReg. + cogit AddCq: 1 R: destReg. + ^0! Item was changed: ----- Method: CogObjectRepresentationForSqueakV3>>genPrimitiveSize (in category 'primitive generators') ----- genPrimitiveSize | jumpSI jumpNotIndexable jumpIsContext | "c.f. StackInterpreter>>stSizeOf: lengthOf:baseHeader:format: fixedFieldsOf:format:length:" <var: #jumpSI type: #'AbstractInstruction *'> <var: #jumpIsContext type: #'AbstractInstruction *'> <var: #jumpNotIndexable type: #'AbstractInstruction *'> jumpSI := self genJumpSmallInteger: ReceiverResultReg. self genGetSizeOf: ReceiverResultReg into: ClassReg formatReg: SendNumArgsReg scratchReg: TempReg abortJumpsInto: [:jnx :jic| jumpNotIndexable := jnx. jumpIsContext := jic]. + self genConvertIntegerInReg: ClassReg toSmallIntegerInReg: ReceiverResultReg. - self genConvertIntegerToSmallIntegerInReg: ClassReg. - cogit MoveR: ClassReg R: ReceiverResultReg. cogit genPrimReturn. jumpSI jmpTarget: (jumpNotIndexable jmpTarget: (jumpIsContext jmpTarget: cogit Label)). ^0! |
Free forum by Nabble | Edit this page |