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! |
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 :
|
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 :
|
Free forum by Nabble | Edit this page |