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

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

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

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

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

Name: VMMaker.oscog-nice.2554
Author: nice
Time: 6 September 2019, 8:02:06.906867 am
UUID: 3c78a4ab-c017-48a8-a05d-f388052996de
Ancestors: VMMaker.oscog-eem.2552

Undo the changes made in VMMaker.oscog-nice.2549 that broke jitted Float nan  < 2.0

Replay Eliot's refactoring on old versions
 s/self genPrimitiveDoMixedArithmetic/coInterpreter primitiveDoMixedArithmetic/

Note: Float comparison are tricky on IA32/X64!
The operator < (jb jump below) test for the carry flag (CF) like a jc, but this carry flag is also set when comparison is unordered !!!
So we must first test the case of unordered, which also set (PF) with a jp.
This is not necessary when using operators >  (above) we can just ja (which is a jnc, case of unordered will set the carry and thus answer false).

By transforming < into >, we avoid a JP conditional jump. Clever!
In VMMaker.oscog-nice.2549, I wanted to simplify this, because I was not aware of this extra complexity.

I'm not sure why nan >= works, because from what i read, unordered case also set the zero flag (ZF)... But since it works I stopped the analysis there...

A short explanation should better be in code comments rather than just this commit message in order to prevent future wild refactorers to break it again ;)
Fortunately we have test cases :)

=============== Diff against VMMaker.oscog-eem.2552 ===============

Item was removed:
- ----- 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 added:
+ ----- 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 primitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpZero
+ orDoubleComparison: #JumpFPEqual:
+ invert: false]
- orDoubleComparison: #JumpFPEqual:]
  ifFalse: [self genSmallIntegerComparison: JumpZero]!

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Item was added:
+ ----- 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 removed:
- ----- 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 added:
+ ----- 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 primitiveDoMixedArithmetic
+ ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
+ ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!
- ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero]
- ifFalse: [self genPureDoubleComparison: #JumpFPEqual:]!

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

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

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

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

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

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

Item was added:
+ ----- 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 removed:
- ----- 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 added:
+ ----- 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!