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