VM Maker: VMMaker.oscog-nice.2549.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-nice.2549.mcz

commits-2
 
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!

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.2549.mcz

Nicolas Cellier
 
Hmm, I may have to revert 2) - for some reason jitted Float comparison fails for Nan < <= (answer true) and succeed for > >= (answer false)
Eliot, do you remember this weirdness?

Le jeu. 5 sept. 2019 à 21:52, <[hidden email]> a écrit :
 
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!

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.2549.mcz

Nicolas Cellier
 
Ah, of course, something like:


So the inversion avoids a test for unordered (jp)... too clever.
I will revert soon, with a comment though.

Le jeu. 5 sept. 2019 à 22:38, Nicolas Cellier <[hidden email]> a écrit :
Hmm, I may have to revert 2) - for some reason jitted Float comparison fails for Nan < <= (answer true) and succeed for > >= (answer false)
Eliot, do you remember this weirdness?

Le jeu. 5 sept. 2019 à 21:52, <[hidden email]> a écrit :
 
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!