[Vm-dev] VM Maker: VMMaker.oscog-nice.2549.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Sep 5 19:52:14 UTC 2019


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2549.mcz

==================== Summary ====================

Name: VMMaker.oscog-nice.2549
Author: nice
Time: 5 September 2019, 9:51:10.740962 pm
UUID: a70fa0be-4c3b-4080-a1f9-ac21d2e5bbea
Ancestors: VMMaker.oscog-nice.2548

3 things:
1) fix generateCheckLZCNT on X64 because MoveCw:R: causes an assertion failure at startup (maxSize=7 < machineCodeSize=11) - I don't understand MoveCw:R:, use MoveCq:R: instead
2) nuke the invert: argument in Float comparison primitives. We have all the necessary instruction for > >= < <= so no use to play with negations
3) be Simulator fiendly by sending messages to objectMemory/coInterpreter/ or whoever

=============== Diff against VMMaker.oscog-nice.2548 ===============

Item was added:
+ ----- Method: CogObjectRepresentation>>genDoubleComparison: (in category 'primitive generators') -----
+ genDoubleComparison: jumpOpcodeGenerator
+ 	<option: #DPFPReg0>
+ 	<var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'>
+ 	| jumpFail jumpImmediate jumpNonInt jumpCond compare |
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpNonInt type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #compare type: #'AbstractInstruction *'>
+ 	<var: #jumpFail type: #'AbstractInstruction *'>
+ 	cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
+ 		[^UnimplementedPrimitive].
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpFail := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	jumpImmediate jmpTarget: cogit Label.
+ 	self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.
+ 	self smallIntegerIsOnlyImmediateType ifFalse:
+ 		[jumpNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].
+ 	self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
+ 	cogit ConvertR: Arg0Reg Rd: DPFPReg1.
+ 	cogit Jump: compare.
+ 	jumpFail jmpTarget: cogit Label.
+ 	self smallIntegerIsOnlyImmediateType ifFalse:
+ 		[jumpNonInt jmpTarget: jumpFail getJmpTarget].
+ 	^CompletePrimitive!

Item was removed:
- ----- Method: CogObjectRepresentation>>genDoubleComparison:invert: (in category 'primitive generators') -----
- genDoubleComparison: jumpOpcodeGenerator invert: invertComparison
- 	<option: #DPFPReg0>
- 	<var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'>
- 	| jumpFail jumpImmediate jumpNonInt jumpCond compare |
- 	<var: #jumpImmediate type: #'AbstractInstruction *'>
- 	<var: #jumpNonInt type: #'AbstractInstruction *'>
- 	<var: #jumpCond type: #'AbstractInstruction *'>
- 	<var: #compare type: #'AbstractInstruction *'>
- 	<var: #jumpFail type: #'AbstractInstruction *'>
- 	cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
- 		[^UnimplementedPrimitive].
- 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
- 	self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
- 	jumpImmediate := self genJumpImmediate: Arg0Reg.
- 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
- 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
- 	jumpFail := cogit JumpNonZero: 0.
- 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
- 	invertComparison "May need to invert for NaNs"
- 		ifTrue: [compare := cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
- 		ifFalse: [compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
- 	jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
- 	cogit genPrimReturn.
- 	jumpImmediate jmpTarget: cogit Label.
- 	self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.
- 	self smallIntegerIsOnlyImmediateType ifFalse:
- 		[jumpNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].
- 	self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
- 	cogit ConvertR: Arg0Reg Rd: DPFPReg1.
- 	cogit Jump: compare.
- 	jumpFail jmpTarget: cogit Label.
- 	self smallIntegerIsOnlyImmediateType ifFalse:
- 		[jumpNonInt jmpTarget: jumpFail getJmpTarget].
- 	^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveEqual (in category 'primitive generators') -----
  genPrimitiveEqual
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self 
  				genSmallIntegerComparison: JumpZero
+ 				orDoubleComparison: #JumpFPEqual:]
- 				orDoubleComparison: #JumpFPEqual:
- 				invert: false]
  		ifFalse: [self genSmallIntegerComparison: JumpZero]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatAdd (in category 'primitive generators') -----
  genPrimitiveFloatAdd
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genDoubleArithmetic: AddRdRd preOpCheck: nil]
  		ifFalse: [self genPureDoubleArithmetic: AddRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatDivide (in category 'primitive generators') -----
  genPrimitiveFloatDivide
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]
  		ifFalse: [self genPureDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatEqual (in category 'primitive generators') -----
  genPrimitiveFloatEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPEqual:]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPEqual: invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatGreaterOrEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual:]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveFloatGreaterThan
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreater:]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatLessOrEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPLessOrEqual:]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPLessOrEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: true]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatLessThan (in category 'primitive generators') -----
  genPrimitiveFloatLessThan
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPLess:]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPLess:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: true]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatMultiply (in category 'primitive generators') -----
  genPrimitiveFloatMultiply
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genDoubleArithmetic: MulRdRd preOpCheck: nil]
  		ifFalse: [self genPureDoubleArithmetic: MulRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveFloatNotEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPNotEqual:]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPNotEqual: invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatSubtract (in category 'primitive generators') -----
  genPrimitiveFloatSubtract
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genDoubleArithmetic: SubRdRd preOpCheck: nil]
  		ifFalse: [self genPureDoubleArithmetic: SubRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveGreaterOrEqual
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self
  				genSmallIntegerComparison: JumpGreaterOrEqual
+ 				orDoubleComparison: #JumpFPGreaterOrEqual:]
- 				orDoubleComparison: #JumpFPGreaterOrEqual:
- 				invert: false]
  		ifFalse: [self genSmallIntegerComparison: JumpGreaterOrEqual]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveGreaterThan (in category 'primitive generators') -----
  genPrimitiveGreaterThan
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self
  				genSmallIntegerComparison: JumpGreater
+ 				orDoubleComparison: #JumpFPGreater:]
- 				orDoubleComparison: #JumpFPGreater:
- 				invert: false]
  		ifFalse: [self genSmallIntegerComparison: JumpGreater]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveLessOrEqual (in category 'primitive generators') -----
  genPrimitiveLessOrEqual
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self
  				genSmallIntegerComparison: JumpLessOrEqual
+ 				orDoubleComparison: #JumpFPLessOrEqual:]
- 				orDoubleComparison: #JumpFPGreaterOrEqual:
- 				invert: true]
  		ifFalse: [self genSmallIntegerComparison: JumpLessOrEqual]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveLessThan (in category 'primitive generators') -----
  genPrimitiveLessThan
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self
  				genSmallIntegerComparison: JumpLess
+ 				orDoubleComparison: #JumpFPLess:]
- 				orDoubleComparison: #JumpFPGreater:
- 				invert: true]
  		ifFalse: [self genSmallIntegerComparison: JumpLess]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveNotEqual (in category 'primitive generators') -----
  genPrimitiveNotEqual
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self 
  				genSmallIntegerComparison: JumpNonZero
+ 				orDoubleComparison: #JumpFPNotEqual:]
- 				orDoubleComparison: #JumpFPNotEqual:
- 				invert: false]
  		ifFalse: [self genSmallIntegerComparison: JumpNonZero]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatAdd (in category 'primitive generators') -----
  genPrimitiveSmallFloatAdd
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genSmallFloatArithmetic: AddRdRd preOpCheck: nil]
  		ifFalse: [self genPureSmallFloatArithmetic: AddRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatDivide (in category 'primitive generators') -----
  genPrimitiveSmallFloatDivide
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]
  		ifFalse: [self genPureSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatEqual
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
- 		ifFalse: [self genPureSmallFloatComparison: #JumpFPEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatGreaterOrEqual
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual ]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: ]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]
- 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveSmallFloatGreaterThan
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater ]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: ]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]
- 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatLessOrEqual
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPLessOrEqual: orIntegerComparison: JumpLessOrEqual ]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPLessOrEqual: ]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]
- 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessThan (in category 'primitive generators') -----
  genPrimitiveSmallFloatLessThan
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPLess: orIntegerComparison: JumpLess ]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPLess: ]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]
- 		ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatMultiply (in category 'primitive generators') -----
  genPrimitiveSmallFloatMultiply
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genSmallFloatArithmetic: MulRdRd preOpCheck: nil]
  		ifFalse: [self genPureSmallFloatArithmetic: MulRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatNotEqual
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero]
+ 		ifFalse: [self genPureSmallFloatComparison: #JumpFPNotEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]
- 		ifFalse: [self genPureSmallFloatComparison: #JumpFPNotEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatSubtract (in category 'primitive generators') -----
  genPrimitiveSmallFloatSubtract
  	<option: #Spur64BitMemoryManager>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
- 	^self getPrimitiveDoMixedArithmetic
  		ifTrue: [self genSmallFloatArithmetic: SubRdRd preOpCheck: nil]
  		ifFalse: [self genPureSmallFloatArithmetic: SubRdRd preOpCheck: nil]!

Item was added:
+ ----- Method: CogObjectRepresentation>>genPureDoubleComparison: (in category 'primitive generators') -----
+ genPureDoubleComparison: jumpOpcodeGenerator
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<option: #DPFPReg0>
+ 	<var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'>
+ 	| jumpFail jumpImmediate jumpCond compare |
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #compare type: #'AbstractInstruction *'>
+ 	<var: #jumpFail type: #'AbstractInstruction *'>
+ 	cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
+ 		[^UnimplementedPrimitive].
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpFail := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	jumpImmediate jmpTarget: cogit Label.
+ 	self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.
+ 	jumpFail jmpTarget: cogit Label.
+ 	^CompletePrimitive!

Item was removed:
- ----- Method: CogObjectRepresentation>>genPureDoubleComparison:invert: (in category 'primitive generators') -----
- genPureDoubleComparison: jumpOpcodeGenerator invert: invertComparison
- 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
- 	<option: #DPFPReg0>
- 	<var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'>
- 	| jumpFail jumpImmediate jumpCond compare |
- 	<var: #jumpImmediate type: #'AbstractInstruction *'>
- 	<var: #jumpCond type: #'AbstractInstruction *'>
- 	<var: #compare type: #'AbstractInstruction *'>
- 	<var: #jumpFail type: #'AbstractInstruction *'>
- 	cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
- 		[^UnimplementedPrimitive].
- 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
- 	self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
- 	jumpImmediate := self genJumpImmediate: Arg0Reg.
- 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
- 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
- 	jumpFail := cogit JumpNonZero: 0.
- 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
- 	invertComparison "May need to invert for NaNs"
- 		ifTrue: [compare := cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
- 		ifFalse: [compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
- 	jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
- 	cogit genPrimReturn.
- 	jumpImmediate jmpTarget: cogit Label.
- 	self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.
- 	jumpFail jmpTarget: cogit Label.
- 	^CompletePrimitive!

Item was added:
+ ----- Method: CogObjectRepresentation>>genSmallIntegerComparison:orDoubleComparison: (in category 'primitive generators') -----
+ genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator
+ 	"Stack looks like
+ 		return address"
+ 	| jumpNonInt jumpFail jumpCond r |
+ 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'>
+ 	<var: #jumpNonInt type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #jumpFail type: #'AbstractInstruction *'>
+ 	r := self genSmallIntegerComparison: jumpOpcode.
+ 	r < 0 ifTrue:
+ 		[^r].
+ 	self cppIf: #DPFPReg0 defined ifTrue:
+ 	"Fall through on non-SmallInteger argument.  Argument may be a Float : let us check or fail"
+ 	[self smallIntegerIsOnlyImmediateType ifFalse:
+ 		[jumpNonInt := self genJumpImmediate: Arg0Reg].
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpFail := cogit JumpNonZero: 0.
+ 
+ 	"It was a Float, so convert the receiver to double and perform the operation"
+ 	self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.
+ 	cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 
+ 	self smallIntegerIsOnlyImmediateType
+ 		ifTrue: [jumpFail jmpTarget: cogit Label]
+ 		ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: cogit Label)]].
+ 	^CompletePrimitive!

Item was removed:
- ----- Method: CogObjectRepresentation>>genSmallIntegerComparison:orDoubleComparison:invert: (in category 'primitive generators') -----
- genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator invert: invertComparison
- 	"Stack looks like
- 		return address"
- 	| jumpNonInt jumpFail jumpCond r |
- 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'>
- 	<var: #jumpNonInt type: #'AbstractInstruction *'>
- 	<var: #jumpCond type: #'AbstractInstruction *'>
- 	<var: #jumpFail type: #'AbstractInstruction *'>
- 	r := self genSmallIntegerComparison: jumpOpcode.
- 	r < 0 ifTrue:
- 		[^r].
- 	self cppIf: #DPFPReg0 defined ifTrue:
- 	"Fall through on non-SmallInteger argument.  Argument may be a Float : let us check or fail"
- 	[self smallIntegerIsOnlyImmediateType ifFalse:
- 		[jumpNonInt := self genJumpImmediate: Arg0Reg].
- 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
- 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
- 	jumpFail := cogit JumpNonZero: 0.
- 
- 	"It was a Float, so convert the receiver to double and perform the operation"
- 	self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.
- 	cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.
- 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
- 	invertComparison "May need to invert for NaNs"
- 		ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
- 		ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
- 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
- 	cogit genPrimReturn.
- 
- 	self smallIntegerIsOnlyImmediateType
- 		ifTrue: [jumpFail jmpTarget: cogit Label]
- 		ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: cogit Label)]].
- 	^CompletePrimitive!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genDoubleComparison:orIntegerComparison: (in category 'primitive generators') -----
+ genDoubleComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode
+ 	<inline: true>
+ 	^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode boxed: true!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genDoubleComparison:orIntegerComparison:invert: (in category 'primitive generators') -----
- genDoubleComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison
- 	<inline: true>
- 	^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison boxed: true!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genFloatComparison:orIntegerComparison:boxed: (in category 'primitive generators') -----
+ genFloatComparison: jumpFPOpcodeGenerator orIntegerComparison: jumpOpcode boxed: rcvrBoxed
+ 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
+ 	<inline: false>
+ 	| jumpImmediate jumpNotSmallFloat jumpNotSmallInteger jumpNotBoxedFloat jumpCond compareFloat jumpNotAmbiguous jumpTrue returnTrue |
+ 	<var: #jumpNotSmallInteger type: #'AbstractInstruction *'>
+ 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpNotAmbiguous type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #jumpTrue type: #'AbstractInstruction *'>
+ 	<var: #returnTrue type: #'AbstractInstruction *'>
+ 	<var: #compareFloat type: #'AbstractInstruction *'>
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	rcvrBoxed
+ 		ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]
+ 		ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].
+ 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
+ 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
+ 	compareFloat := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	
+ 	jumpNotSmallFloat jmpTarget: cogit Label.
+ 	jumpNotSmallInteger := self genJumpNotSmallInteger: Arg0Reg.
+ 	"Test for ambiguity, that is when floatRcvr == (double) intArg"
+ 	self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
+ 	cogit ConvertR: Arg0Reg Rd: DPFPReg1.
+ 	cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	"If floatRcvr !!= (double) intArg then use compareFloat(floatRcvr,(double) intArg)"
+ 	"else use compareInt(intArg,(int64) floatRcvr)"
+ 	jumpNotAmbiguous := cogit perform: #JumpFPNotEqual: with: 0.
+ 	"Case of non ambiguity, use compareFloat(floatRcvr,(double) intArg)"
+ 	jumpNotAmbiguous jmpTarget: compareFloat.
+ 	"Case of ambiguity, use compareInt((int64) floatRcvr, intArg)"
+ 	cogit ConvertRd: DPFPReg0 R: ReceiverResultReg.
+ 	cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"
+ 	jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpTrue jmpTarget: returnTrue.
+ 
+ 	"not a Small Float, nor Small Integer, check for Boxed Float argument"
+ 	jumpNotSmallInteger jmpTarget: cogit Label.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	cogit Jump: compareFloat.
+ 	
+ 	jumpImmediate jmpTarget:
+ 	(jumpNotBoxedFloat jmpTarget: cogit Label).
+ 	^CompletePrimitive!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genFloatComparison:orIntegerComparison:invert:boxed: (in category 'primitive generators') -----
- genFloatComparison: jumpFPOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison boxed: rcvrBoxed
- 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
- 	<inline: false>
- 	| jumpImmediate jumpNotSmallFloat jumpNotSmallInteger jumpNotBoxedFloat jumpCond compareFloat jumpAmbiguous jumpTrue returnTrue |
- 	<var: #jumpNotSmallInteger type: #'AbstractInstruction *'>
- 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
- 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
- 	<var: #jumpImmediate type: #'AbstractInstruction *'>
- 	<var: #jumpAmbiguous type: #'AbstractInstruction *'>
- 	<var: #jumpCond type: #'AbstractInstruction *'>
- 	<var: #jumpTrue type: #'AbstractInstruction *'>
- 	<var: #returnTrue type: #'AbstractInstruction *'>
- 	<var: #compareFloat type: #'AbstractInstruction *'>
- 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
- 	rcvrBoxed
- 		ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]
- 		ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].
- 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
- 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
- 	compareFloat := invertComparison "May need to invert for NaNs"
- 					ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
- 					ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
- 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).
- 	cogit genPrimReturn.
- 	
- 	jumpNotSmallFloat jmpTarget: cogit Label.
- 	jumpNotSmallInteger := self genJumpNotSmallInteger: Arg0Reg.
- 	"Test for ambiguity, that is when floatRcvr == (double) intArg"
- 	self genConvertSmallIntegerToIntegerInReg: Arg0Reg.
- 	cogit ConvertR: Arg0Reg Rd: DPFPReg1.
- 	cogit CmpRd: DPFPReg0 Rd: DPFPReg1.
- 	"If floatRcvr == (double) intArg then use compareInt(intArg,(int64) floatRcvr)"
- 	"else use compareFloat(floatRcvr,(double) intArg)"
- 	jumpAmbiguous := cogit perform: #JumpFPEqual: with: 0.
- 	"Case of non ambiguity, use compareFloat(floatRcvr,(double) intArg)"
- 	cogit Jump: compareFloat.
- 	"Case of ambiguity, use compareInt((int64) floatRcvr, intArg)"
- 	jumpAmbiguous jmpTarget: (cogit ConvertRd: DPFPReg0 R: ReceiverResultReg).
- 	cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"
- 	jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpTrue jmpTarget: returnTrue.
- 
- 	"not a Small Float, nor Small Integer, check for Boxed Float argument"
- 	jumpNotSmallInteger jmpTarget: cogit Label.
- 	jumpImmediate := self genJumpImmediate: Arg0Reg.
- 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
- 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
- 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
- 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
- 	cogit Jump: compareFloat.
- 	
- 	jumpImmediate jmpTarget:
- 	(jumpNotBoxedFloat jmpTarget: cogit Label).
- 	^CompletePrimitive!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatEqual (in category 'primitive generators') -----
  genPrimitiveFloatEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatGreaterOrEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveFloatGreaterThan
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatLessOrEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPLessOrEqual: orIntegerComparison: JumpLessOrEqual]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPLessOrEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessThan (in category 'primitive generators') -----
  genPrimitiveFloatLessThan
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPLess: orIntegerComparison: JumpLess]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPLess:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveFloatNotEqual
  	<option: #DPFPReg0>
+ 	^coInterpreter getPrimitiveDoMixedArithmetic
+ 		ifTrue: [self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero]
+ 		ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual:]!
- 	^self getPrimitiveDoMixedArithmetic
- 		ifTrue: [self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]
- 		ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureDoubleComparison: (in category 'primitive generators') -----
+ genPureDoubleComparison: jumpOpcodeGenerator
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<inline: true>
+ 	^self genPureFloatComparison: jumpOpcodeGenerator boxed: true!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPureDoubleComparison:invert: (in category 'primitive generators') -----
- genPureDoubleComparison: jumpOpcodeGenerator invert: invertComparison
- 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
- 	<inline: true>
- 	^self genPureFloatComparison: jumpOpcodeGenerator invert: invertComparison boxed: true!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureFloatComparison:boxed: (in category 'primitive generators') -----
+ genPureFloatComparison: jumpFPOpcodeGenerator boxed: rcvrBoxed
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
+ 	<inline: false>
+ 	| jumpImmediate jumpNotSmallFloat jumpNotBoxedFloat jumpCond compareFloat |
+ 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpImmediate type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #compareFloat type: #'AbstractInstruction *'>
+ 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
+ 	rcvrBoxed
+ 		ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]
+ 		ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].
+ 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
+ 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
+ 	compareFloat := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	
+ 	"not a Small Float, check for Boxed Float argument"
+ 	jumpNotSmallFloat jmpTarget: cogit Label.
+ 	jumpImmediate := self genJumpImmediate: Arg0Reg.
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	cogit Jump: compareFloat.
+ 	
+ 	jumpImmediate jmpTarget:
+ 	(jumpNotBoxedFloat jmpTarget: cogit Label).
+ 	^CompletePrimitive!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPureFloatComparison:invert:boxed: (in category 'primitive generators') -----
- genPureFloatComparison: jumpFPOpcodeGenerator invert: invertComparison boxed: rcvrBoxed
- 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
- 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'>
- 	<inline: false>
- 	| jumpImmediate jumpNotSmallFloat jumpNotBoxedFloat jumpCond compareFloat |
- 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
- 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
- 	<var: #jumpImmediate type: #'AbstractInstruction *'>
- 	<var: #jumpCond type: #'AbstractInstruction *'>
- 	<var: #compareFloat type: #'AbstractInstruction *'>
- 	cogit genLoadArgAtDepth: 0 into: Arg0Reg.
- 	rcvrBoxed
- 		ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]
- 		ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].
- 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
- 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
- 	compareFloat := invertComparison "May need to invert for NaNs"
- 					ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
- 					ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
- 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).
- 	cogit genPrimReturn.
- 	
- 	"not a Small Float, check for Boxed Float argument"
- 	jumpNotSmallFloat jmpTarget: cogit Label.
- 	jumpImmediate := self genJumpImmediate: Arg0Reg.
- 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
- 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
- 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
- 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
- 	cogit Jump: compareFloat.
- 	
- 	jumpImmediate jmpTarget:
- 	(jumpNotBoxedFloat jmpTarget: cogit Label).
- 	^CompletePrimitive!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureSmallFloatComparison: (in category 'primitive generators') -----
+ genPureSmallFloatComparison: jumpOpcodeGenerator
+ 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
+ 	<inline: true>
+ 	^self genPureFloatComparison: jumpOpcodeGenerator boxed: false!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPureSmallFloatComparison:invert: (in category 'primitive generators') -----
- genPureSmallFloatComparison: jumpOpcodeGenerator invert: invertComparison
- 	"In the Pure version, mixed arithmetic with SmallInteger is forbidden"
- 	<inline: true>
- 	^self genPureFloatComparison: jumpOpcodeGenerator invert: invertComparison boxed: false!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallFloatComparison:orIntegerComparison: (in category 'primitive generators') -----
+ genSmallFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode
+ 	<inline: true>
+ 	^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode boxed: false!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallFloatComparison:orIntegerComparison:invert: (in category 'primitive generators') -----
- genSmallFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison
- 	<inline: true>
- 	^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison boxed: false!

Item was added:
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallIntegerComparison:orDoubleComparison: (in category 'primitive generators') -----
+ genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator
+ 	"Stack looks like
+ 		return address"
+ 	| jumpCond r compareIntFloat jumpAmbiguous jumpNotBoxedFloat jumpNotFloatAtAll jumpNotSmallFloat jumpTrue returnTrue |
+ 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'>
+ 	<var: #jumpNonInt type: #'AbstractInstruction *'>
+ 	<var: #jumpCond type: #'AbstractInstruction *'>
+ 	<var: #jumpTrue type: #'AbstractInstruction *'>
+ 	<var: #returnTrue type: #'AbstractInstruction *'>
+ 	<var: #jumpAmbiguous type: #'AbstractInstruction *'>
+ 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
+ 	<var: #jumpNotFloatAtAll type: #'AbstractInstruction *'>
+ 	<var: #compareIntFloat type: #'AbstractInstruction *'>
+ 	r := self genSmallIntegerComparison: jumpOpcode.
+ 	r < 0 ifTrue:
+ 		[^r].
+ 	self cppIf: #DPFPReg0 defined ifTrue:
+ 	"Fall through on non-SmallInteger argument.  Argument may be a Float : let us check or fail"
+ 	[
+ 	"check for Small Float argument"
+ 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
+ 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
+ 	
+ 	"Case of (int compare: float). Test for ambiguity, that is when (double) intRcvr == floatArg"
+ 	compareIntFloat := cogit Label.
+ 	self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.
+ 	cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.
+ 	cogit CmpRd: DPFPReg0 Rd: DPFPReg1.
+ 	jumpAmbiguous := cogit perform: #JumpFPEqual: with: 0.
+ 	"Case of non ambiguity, use compareFloat((double) intRcvr,floatArg)"
+ 	cogit CmpRd: DPFPReg1 Rd: DPFPReg0.
+ 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).
+ 	cogit genPrimReturn.
+ 	"Case of ambiguity, use compareInt(intRcvr , (int64) floatArg)"
+ 	jumpAmbiguous jmpTarget: (cogit ConvertRd: DPFPReg1 R: Arg0Reg).
+ 	cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"
+ 	jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.
+ 	cogit genMoveFalseR: ReceiverResultReg.
+ 	cogit genPrimReturn.
+ 	jumpTrue jmpTarget: returnTrue.
+ 					
+ 	"not a Small Float, check for Boxed Float argument"
+ 	jumpNotSmallFloat jmpTarget: (jumpNotFloatAtAll := self genJumpImmediate: Arg0Reg).
+ 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
+ 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
+ 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
+ 	"It was a Boxed Float, so convert the receiver to double and perform the (int compare: float) operation"
+ 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
+ 	cogit Jump: compareIntFloat.
+ 	
+ 	"not a Float, just let the primitive fall thru failure"
+ 	jumpNotBoxedFloat jmpTarget: (jumpNotFloatAtAll jmpTarget: cogit Label)].
+ 	^CompletePrimitive!

Item was removed:
- ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallIntegerComparison:orDoubleComparison:invert: (in category 'primitive generators') -----
- genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator invert: invertComparison
- 	"Stack looks like
- 		return address"
- 	| jumpCond r compareIntFloat jumpAmbiguous jumpNotBoxedFloat jumpNotFloatAtAll jumpNotSmallFloat jumpTrue returnTrue |
- 	<var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'>
- 	<var: #jumpNonInt type: #'AbstractInstruction *'>
- 	<var: #jumpCond type: #'AbstractInstruction *'>
- 	<var: #jumpTrue type: #'AbstractInstruction *'>
- 	<var: #returnTrue type: #'AbstractInstruction *'>
- 	<var: #jumpAmbiguous type: #'AbstractInstruction *'>
- 	<var: #jumpNotBoxedFloat type: #'AbstractInstruction *'>
- 	<var: #jumpNotSmallFloat type: #'AbstractInstruction *'>
- 	<var: #jumpNotFloatAtAll type: #'AbstractInstruction *'>
- 	<var: #compareIntFloat type: #'AbstractInstruction *'>
- 	r := self genSmallIntegerComparison: jumpOpcode.
- 	r < 0 ifTrue:
- 		[^r].
- 	self cppIf: #DPFPReg0 defined ifTrue:
- 	"Fall through on non-SmallInteger argument.  Argument may be a Float : let us check or fail"
- 	[
- 	"check for Small Float argument"
- 	jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.
- 	self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.
- 	
- 	"Case of (int compare: float). Test for ambiguity, that is when (double) intRcvr == floatArg"
- 	compareIntFloat := cogit Label.
- 	self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.
- 	cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.
- 	cogit CmpRd: DPFPReg0 Rd: DPFPReg1.
- 	jumpAmbiguous := cogit perform: #JumpFPEqual: with: 0.
- 	"Case of non ambiguity, use compareFloat((double) intRcvr,floatArg)"
- 	invertComparison "May need to invert for NaNs"
- 					ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]
- 					ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].
- 	jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).
- 	cogit genPrimReturn.
- 	"Case of ambiguity, use compareInt(intRcvr , (int64) floatArg)"
- 	jumpAmbiguous jmpTarget: (cogit ConvertRd: DPFPReg1 R: Arg0Reg).
- 	cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"
- 	jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.
- 	cogit genMoveFalseR: ReceiverResultReg.
- 	cogit genPrimReturn.
- 	jumpTrue jmpTarget: returnTrue.
- 					
- 	"not a Small Float, check for Boxed Float argument"
- 	jumpNotSmallFloat jmpTarget: (jumpNotFloatAtAll := self genJumpImmediate: Arg0Reg).
- 	self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.
- 	self genCmpClassFloatCompactIndexR: SendNumArgsReg.
- 	jumpNotBoxedFloat := cogit JumpNonZero: 0.
- 	"It was a Boxed Float, so convert the receiver to double and perform the (int compare: float) operation"
- 	self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.
- 	cogit Jump: compareIntFloat.
- 	
- 	"not a Float, just let the primitive fall thru failure"
- 	jumpNotBoxedFloat jmpTarget: (jumpNotFloatAtAll jmpTarget: cogit Label)].
- 	^CompletePrimitive!

Item was changed:
  ----- Method: CogX64Compiler>>generateCheckLZCNT (in category 'feature detection') -----
  generateCheckLZCNT
  	"to check is Leading Zero Count operation is present
  	cf. MSVC builtin __lzcnt documentation
  	The result will be in bit 5 of return value (in RAX)"
  	cogit
  		PushR: RDX;
  		PushR: RCX;
  		PushR: RBX;
+ 		MoveCq: 16r80000001 R: RAX;
- 		MoveCw: 16r80000001 R: RAX;
  		gen: CPUID;
  		MoveR: RCX R: RAX;
  		PopR: RBX;
  		PopR: RCX;
  		PopR: RDX;
  		RetN: 0!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatEqual
  	<option: #Spur64BitMemoryManager>
  	| rcvr arg intArg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  	arg := objectMemory loadFloatOrIntFrom: self stackTop.
  	self successful ifTrue:
  		[self cppIf: objectMemory wordSize > 4
+ 			ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- 			ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])
  				ifTrue:
  					["Resolve case of ambiguity so as to have comparison of exact values"
+ 					intArg := objectMemory integerValueOf: self stackTop.
- 					intArg := self integerValueOf: self stackTop.
  					self pop: 2 thenPushBool: rcvr asInteger = intArg]
  				ifFalse: [self pop: 2 thenPushBool: rcvr = arg]]
  			ifFalse: [self pop: 2 thenPushBool: rcvr = arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatGreaterOrEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatGreaterOrEqual
  	<option: #Spur64BitMemoryManager>
  	| rcvr arg intArg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  	arg := objectMemory loadFloatOrIntFrom: self stackTop.
  	self successful ifTrue:
  		[self cppIf: objectMemory wordSize > 4
+ 			ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- 			ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])
  				ifTrue:
  					["Resolve case of ambiguity so as to have comparison of exact values"
+ 					intArg := objectMemory integerValueOf: self stackTop.
- 					intArg := self integerValueOf: self stackTop.
  					self pop: 2 thenPushBool: rcvr asInteger >= intArg]
  				ifFalse: [self pop: 2 thenPushBool: rcvr >= arg]]
  			ifFalse: [self pop: 2 thenPushBool: rcvr >= arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatGreaterThan (in category 'arithmetic float primitives') -----
  primitiveSmallFloatGreaterThan
  	<option: #Spur64BitMemoryManager>
  	| rcvr arg intArg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  	arg := objectMemory loadFloatOrIntFrom: self stackTop.
  	self successful ifTrue:
  		[self cppIf: objectMemory wordSize > 4
+ 			ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- 			ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])
  				ifTrue:
  					["Resolve case of ambiguity so as to have comparison of exact values"
+ 					intArg := objectMemory integerValueOf: self stackTop.
- 					intArg := self integerValueOf: self stackTop.
  					self pop: 2 thenPushBool: rcvr asInteger > intArg]
  				ifFalse: [self pop: 2 thenPushBool: rcvr > arg]]
  			ifFalse: [self pop: 2 thenPushBool: rcvr > arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatLessOrEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatLessOrEqual
  	<option: #Spur64BitMemoryManager>
  	| rcvr arg intArg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  	arg := objectMemory loadFloatOrIntFrom: self stackTop.
  	self successful ifTrue:
  		[self cppIf: objectMemory wordSize > 4
+ 			ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- 			ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])
  				ifTrue:
  					["Resolve case of ambiguity so as to have comparison of exact values"
+ 					intArg := objectMemory integerValueOf: self stackTop.
- 					intArg := self integerValueOf: self stackTop.
  					self pop: 2 thenPushBool: rcvr asInteger <= intArg]
  				ifFalse: [self pop: 2 thenPushBool: rcvr <= arg]]
  			ifFalse: [self pop: 2 thenPushBool: rcvr <= arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatLessThan (in category 'arithmetic float primitives') -----
  primitiveSmallFloatLessThan
  	<option: #Spur64BitMemoryManager>
  	| rcvr arg intArg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  	arg := objectMemory loadFloatOrIntFrom: self stackTop.
  	self successful ifTrue:
  		[self cppIf: objectMemory wordSize > 4
+ 			ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- 			ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])
  				ifTrue:
  					["Resolve case of ambiguity so as to have comparison of exact values"
+ 					intArg := objectMemory integerValueOf: self stackTop.
- 					intArg := self integerValueOf: self stackTop.
  					self pop: 2 thenPushBool: rcvr asInteger < intArg]
  				ifFalse: [self pop: 2 thenPushBool: rcvr < arg]]
  			ifFalse: [self pop: 2 thenPushBool: rcvr < arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatNotEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatNotEqual
  	<option: #Spur64BitMemoryManager>
  	| rcvr arg intArg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  	arg := objectMemory loadFloatOrIntFrom: self stackTop.
  	self successful ifTrue:
  		[self cppIf: objectMemory wordSize > 4
+ 			ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- 			ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])
  				ifTrue: ["Resolve case of ambiguity so as to have comparison of exact values"
+ 					intArg := objectMemory integerValueOf: self stackTop.
- 					intArg := self integerValueOf: self stackTop.
  					self pop: 2 thenPushBool: (rcvr asInteger = intArg) not]
  				ifFalse: [self pop: 2 thenPushBool: (rcvr = arg) not]]
  			ifFalse: [self pop: 2 thenPushBool: (rcvr = arg) not]]!

Item was changed:
  ----- Method: Spur64BitMemoryManager>>loadFloatOrIntFrom: (in category 'interpreter access') -----
  loadFloatOrIntFrom: floatOrIntOop
  	"If floatOrInt is an integer and we enable mixed arithmetic in primitives, then convert it to a C double float and return it.
  	 If it is a Float, then load its value and return it.
  	 Otherwise fail -- ie return with primErrorCode non-zero."
  
  	<inline: true>
  	<returnTypeC: #double>
  	| result tagBits |
  	<var: #result type: #double>
  
  	(tagBits := floatOrIntOop bitAnd: self tagMask) ~= 0
  		ifTrue:
  			[tagBits = self smallFloatTag ifTrue:
  				[^self smallFloatValueOf: floatOrIntOop].
+ 			 (coInterpreter primitiveDoMixedArithmetic and: [tagBits = self smallIntegerTag]) ifTrue:
- 			 (self primitiveDoMixedArithmetic and: [tagBits = self smallIntegerTag]) ifTrue:
  				[^(self integerValueOf: floatOrIntOop) asFloat]]
  		ifFalse:
  			[(self classIndexOf: floatOrIntOop) = ClassFloatCompactIndex ifTrue:
  				[self cCode: '' inSmalltalk: [result := Float new: 2].
  				 self fetchFloatAt: floatOrIntOop + self baseHeaderSize into: result.
  				 ^result]].
  	coInterpreter primitiveFail.
  	^0.0!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatEqual:toArg: (in category 'comparison float primitives') -----
  primitiveFloatEqual: rcvrOop toArg: argOop
  	| rcvr arg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  	arg := objectMemory loadFloatOrIntFrom: argOop.
  	self cppIf: objectMemory wordSize > 4
  		ifTrue: [rcvr = arg
  			ifTrue:
+ 				[(objectMemory isIntegerObject: argOop)
- 				[(self isIntegerObject: argOop)
  					ifTrue:
  						["Resolve case of ambiguity so as to have comparison of exact values"
+ 						^ rcvr asInteger = (objectMemory integerValueOf: argOop)]
+ 					ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- 						^ rcvr asInteger = (self integerValueOf: argOop)]
- 					ifFalse: [(self isIntegerObject: rcvrOop)
  						ifTrue:
  							["Same when used from bytecodePrim...
  							note that rcvr and arg cannot be both integer (case is already handled)"
+ 							^ (objectMemory integerValueOf: rcvrOop) = arg asInteger]]]].
- 							^ (self integerValueOf: rcvrOop) = arg asInteger]]]].
  	^rcvr = arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatGreater:thanArg: (in category 'comparison float primitives') -----
  primitiveFloatGreater: rcvrOop thanArg: argOop
  	| rcvr arg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  	arg := objectMemory loadFloatOrIntFrom: argOop.
  	self cppIf: objectMemory wordSize > 4
  		ifTrue: [rcvr = arg
  			ifTrue:
+ 				[(objectMemory isIntegerObject: argOop)
- 				[(self isIntegerObject: argOop)
  					ifTrue:
  						["Resolve case of ambiguity so as to have comparison of exact values"
+ 						^ rcvr asInteger > (objectMemory integerValueOf: argOop)]
+ 					ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- 						^ rcvr asInteger > (self integerValueOf: argOop)]
- 					ifFalse: [(self isIntegerObject: rcvrOop)
  						ifTrue:
  							["Same when used from bytecodePrim...
  							note that rcvr and arg cannot be both integer (case is already handled)"
+ 							^ (objectMemory integerValueOf: rcvrOop) > arg asInteger]]]].
- 							^ (self integerValueOf: rcvrOop) > arg asInteger]]]].
  	^rcvr > arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatGreaterOrEqual:toArg: (in category 'comparison float primitives') -----
  primitiveFloatGreaterOrEqual: rcvrOop toArg: argOop
  	| rcvr arg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  	arg := objectMemory loadFloatOrIntFrom: argOop.
  	self cppIf: objectMemory wordSize > 4
  		ifTrue: [rcvr = arg
  			ifTrue:
+ 				[(objectMemory isIntegerObject: argOop)
- 				[(self isIntegerObject: argOop)
  					ifTrue:
  						["Resolve case of ambiguity so as to have comparison of exact values"
+ 						^ rcvr asInteger >= (objectMemory integerValueOf: argOop)]
+ 					ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- 						^ rcvr asInteger >= (self integerValueOf: argOop)]
- 					ifFalse: [(self isIntegerObject: rcvrOop)
  						ifTrue:
  							["Same when used from bytecodePrim...
  							note that rcvr and arg cannot be both integer (case is already handled)"
+ 							^ (objectMemory integerValueOf: rcvrOop) >= arg asInteger]]]].
- 							^ (self integerValueOf: rcvrOop) >= arg asInteger]]]].
  	^rcvr >= arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatLess:thanArg: (in category 'comparison float primitives') -----
  primitiveFloatLess: rcvrOop thanArg: argOop
  	| rcvr arg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  	arg := objectMemory loadFloatOrIntFrom: argOop.
  	self cppIf: objectMemory wordSize > 4
  		ifTrue: [rcvr = arg
  			ifTrue:
+ 				[(objectMemory isIntegerObject: argOop)
- 				[(self isIntegerObject: argOop)
  					ifTrue:
  						["Resolve case of ambiguity so as to have comparison of exact values"
+ 						^ rcvr asInteger < (objectMemory integerValueOf: argOop)]
+ 					ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- 						^ rcvr asInteger < (self integerValueOf: argOop)]
- 					ifFalse: [(self isIntegerObject: rcvrOop)
  						ifTrue:
  							["Same when used from bytecodePrim...
  							note that rcvr and arg cannot be both integer (case is already handled)"
+ 							^ (objectMemory integerValueOf: rcvrOop) < arg asInteger]]]].
- 							^ (self integerValueOf: rcvrOop) < arg asInteger]]]].
  	^rcvr < arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatLessOrEqual:toArg: (in category 'comparison float primitives') -----
  primitiveFloatLessOrEqual: rcvrOop toArg: argOop
  	| rcvr arg |
  	<var: #rcvr type: #double>
  	<var: #arg type: #double>
  
  	rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  	arg := objectMemory loadFloatOrIntFrom: argOop.
  	self cppIf: objectMemory wordSize > 4
  		ifTrue: [rcvr = arg
  			ifTrue:
+ 				[(objectMemory isIntegerObject: argOop)
- 				[(self isIntegerObject: argOop)
  					ifTrue:
  						["Resolve case of ambiguity so as to have comparison of exact values"
+ 						^ rcvr asInteger <= (objectMemory integerValueOf: argOop)]
+ 					ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- 						^ rcvr asInteger <= (self integerValueOf: argOop)]
- 					ifFalse: [(self isIntegerObject: rcvrOop)
  						ifTrue:
  							["Same when used from bytecodePrim...
  							note that rcvr and arg cannot be both integer (case is already handled)"
+ 							^ (objectMemory integerValueOf: rcvrOop) <= arg asInteger]]]].
- 							^ (self integerValueOf: rcvrOop) <= arg asInteger]]]].
  	^rcvr <= arg!



More information about the Vm-dev mailing list