<div dir="ltr"><div>Hmm, I may have to revert 2) - for some reason jitted Float comparison fails for Nan < <= (answer true) and succeed for > >= (answer false)<br></div>Eliot, do you remember this weirdness?<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le jeu. 5 sept. 2019 à 21:52, <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> <br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2549.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2549.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.2549<br>
Author: nice<br>
Time: 5 September 2019, 9:51:10.740962 pm<br>
UUID: a70fa0be-4c3b-4080-a1f9-ac21d2e5bbea<br>
Ancestors: VMMaker.oscog-nice.2548<br>
<br>
3 things:<br>
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<br>
2) nuke the invert: argument in Float comparison primitives. We have all the necessary instruction for > >= < <= so no use to play with negations<br>
3) be Simulator fiendly by sending messages to objectMemory/coInterpreter/ or whoever<br>
<br>
=============== Diff against VMMaker.oscog-nice.2548 ===============<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentation>>genDoubleComparison: (in category 'primitive generators') -----<br>
+ genDoubleComparison: jumpOpcodeGenerator<br>
+ <option: #DPFPReg0><br>
+ <var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'><br>
+ | jumpFail jumpImmediate jumpNonInt jumpCond compare |<br>
+ <var: #jumpImmediate type: #'AbstractInstruction *'><br>
+ <var: #jumpNonInt type: #'AbstractInstruction *'><br>
+ <var: #jumpCond type: #'AbstractInstruction *'><br>
+ <var: #compare type: #'AbstractInstruction *'><br>
+ <var: #jumpFail type: #'AbstractInstruction *'><br>
+ cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:<br>
+ [^UnimplementedPrimitive].<br>
+ cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
+ self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.<br>
+ jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
+ self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
+ self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
+ jumpFail := cogit JumpNonZero: 0.<br>
+ self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
+ compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
+ cogit genPrimReturn.<br>
+ jumpImmediate jmpTarget: cogit Label.<br>
+ self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.<br>
+ self smallIntegerIsOnlyImmediateType ifFalse:<br>
+ [jumpNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].<br>
+ self genConvertSmallIntegerToIntegerInReg: Arg0Reg.<br>
+ cogit ConvertR: Arg0Reg Rd: DPFPReg1.<br>
+ cogit Jump: compare.<br>
+ jumpFail jmpTarget: cogit Label.<br>
+ self smallIntegerIsOnlyImmediateType ifFalse:<br>
+ [jumpNonInt jmpTarget: jumpFail getJmpTarget].<br>
+ ^CompletePrimitive!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentation>>genDoubleComparison:invert: (in category 'primitive generators') -----<br>
- genDoubleComparison: jumpOpcodeGenerator invert: invertComparison<br>
- <option: #DPFPReg0><br>
- <var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'><br>
- | jumpFail jumpImmediate jumpNonInt jumpCond compare |<br>
- <var: #jumpImmediate type: #'AbstractInstruction *'><br>
- <var: #jumpNonInt type: #'AbstractInstruction *'><br>
- <var: #jumpCond type: #'AbstractInstruction *'><br>
- <var: #compare type: #'AbstractInstruction *'><br>
- <var: #jumpFail type: #'AbstractInstruction *'><br>
- cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:<br>
- [^UnimplementedPrimitive].<br>
- cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
- self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.<br>
- jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
- self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
- self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
- jumpFail := cogit JumpNonZero: 0.<br>
- self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
- invertComparison "May need to invert for NaNs"<br>
- ifTrue: [compare := cogit CmpRd: DPFPReg0 Rd: DPFPReg1]<br>
- ifFalse: [compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0].<br>
- jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
- cogit genPrimReturn.<br>
- jumpImmediate jmpTarget: cogit Label.<br>
- self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.<br>
- self smallIntegerIsOnlyImmediateType ifFalse:<br>
- [jumpNonInt := self genJumpNotSmallInteger: Arg0Reg scratchReg: TempReg].<br>
- self genConvertSmallIntegerToIntegerInReg: Arg0Reg.<br>
- cogit ConvertR: Arg0Reg Rd: DPFPReg1.<br>
- cogit Jump: compare.<br>
- jumpFail jmpTarget: cogit Label.<br>
- self smallIntegerIsOnlyImmediateType ifFalse:<br>
- [jumpNonInt jmpTarget: jumpFail getJmpTarget].<br>
- ^CompletePrimitive!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveEqual (in category 'primitive generators') -----<br>
genPrimitiveEqual<br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self <br>
genSmallIntegerComparison: JumpZero<br>
+ orDoubleComparison: #JumpFPEqual:]<br>
- orDoubleComparison: #JumpFPEqual:<br>
- invert: false]<br>
ifFalse: [self genSmallIntegerComparison: JumpZero]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatAdd (in category 'primitive generators') -----<br>
genPrimitiveFloatAdd<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genDoubleArithmetic: AddRdRd preOpCheck: nil]<br>
ifFalse: [self genPureDoubleArithmetic: AddRdRd preOpCheck: nil]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatDivide (in category 'primitive generators') -----<br>
genPrimitiveFloatDivide<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]<br>
ifFalse: [self genPureDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPEqual:]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPEqual: invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatGreaterOrEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual:]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----<br>
genPrimitiveFloatGreaterThan<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPGreater:]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPGreater:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatLessOrEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPLessOrEqual:]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPLessOrEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: true]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatLessThan (in category 'primitive generators') -----<br>
genPrimitiveFloatLessThan<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPLess:]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPLess:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: true]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatMultiply (in category 'primitive generators') -----<br>
genPrimitiveFloatMultiply<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genDoubleArithmetic: MulRdRd preOpCheck: nil]<br>
ifFalse: [self genPureDoubleArithmetic: MulRdRd preOpCheck: nil]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatNotEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPNotEqual:]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPNotEqual: invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveFloatSubtract (in category 'primitive generators') -----<br>
genPrimitiveFloatSubtract<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genDoubleArithmetic: SubRdRd preOpCheck: nil]<br>
ifFalse: [self genPureDoubleArithmetic: SubRdRd preOpCheck: nil]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveGreaterOrEqual (in category 'primitive generators') -----<br>
genPrimitiveGreaterOrEqual<br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self<br>
genSmallIntegerComparison: JumpGreaterOrEqual<br>
+ orDoubleComparison: #JumpFPGreaterOrEqual:]<br>
- orDoubleComparison: #JumpFPGreaterOrEqual:<br>
- invert: false]<br>
ifFalse: [self genSmallIntegerComparison: JumpGreaterOrEqual]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveGreaterThan (in category 'primitive generators') -----<br>
genPrimitiveGreaterThan<br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self<br>
genSmallIntegerComparison: JumpGreater<br>
+ orDoubleComparison: #JumpFPGreater:]<br>
- orDoubleComparison: #JumpFPGreater:<br>
- invert: false]<br>
ifFalse: [self genSmallIntegerComparison: JumpGreater]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveLessOrEqual (in category 'primitive generators') -----<br>
genPrimitiveLessOrEqual<br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self<br>
genSmallIntegerComparison: JumpLessOrEqual<br>
+ orDoubleComparison: #JumpFPLessOrEqual:]<br>
- orDoubleComparison: #JumpFPGreaterOrEqual:<br>
- invert: true]<br>
ifFalse: [self genSmallIntegerComparison: JumpLessOrEqual]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveLessThan (in category 'primitive generators') -----<br>
genPrimitiveLessThan<br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self<br>
genSmallIntegerComparison: JumpLess<br>
+ orDoubleComparison: #JumpFPLess:]<br>
- orDoubleComparison: #JumpFPGreater:<br>
- invert: true]<br>
ifFalse: [self genSmallIntegerComparison: JumpLess]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveNotEqual (in category 'primitive generators') -----<br>
genPrimitiveNotEqual<br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self <br>
genSmallIntegerComparison: JumpNonZero<br>
+ orDoubleComparison: #JumpFPNotEqual:]<br>
- orDoubleComparison: #JumpFPNotEqual:<br>
- invert: false]<br>
ifFalse: [self genSmallIntegerComparison: JumpNonZero]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatAdd (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatAdd<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genSmallFloatArithmetic: AddRdRd preOpCheck: nil]<br>
ifFalse: [self genPureSmallFloatArithmetic: AddRdRd preOpCheck: nil]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatDivide (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatDivide<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]<br>
ifFalse: [self genPureSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatEqual (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatEqual<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero]<br>
+ ifFalse: [self genPureSmallFloatComparison: #JumpFPEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]<br>
- ifFalse: [self genPureSmallFloatComparison: #JumpFPEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterOrEqual (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatGreaterOrEqual<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual ]<br>
+ ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: ]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]<br>
- ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterThan (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatGreaterThan<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater ]<br>
+ ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: ]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]<br>
- ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessOrEqual (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatLessOrEqual<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genSmallFloatComparison: #JumpFPLessOrEqual: orIntegerComparison: JumpLessOrEqual ]<br>
+ ifFalse: [self genPureSmallFloatComparison: #JumpFPLessOrEqual: ]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]<br>
- ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: true]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessThan (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatLessThan<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genSmallFloatComparison: #JumpFPLess: orIntegerComparison: JumpLess ]<br>
+ ifFalse: [self genPureSmallFloatComparison: #JumpFPLess: ]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]<br>
- ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: true]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatMultiply (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatMultiply<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genSmallFloatArithmetic: MulRdRd preOpCheck: nil]<br>
ifFalse: [self genPureSmallFloatArithmetic: MulRdRd preOpCheck: nil]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatNotEqual (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatNotEqual<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero]<br>
+ ifFalse: [self genPureSmallFloatComparison: #JumpFPNotEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]<br>
- ifFalse: [self genPureSmallFloatComparison: #JumpFPNotEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatSubtract (in category 'primitive generators') -----<br>
genPrimitiveSmallFloatSubtract<br>
<option: #Spur64BitMemoryManager><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
- ^self getPrimitiveDoMixedArithmetic<br>
ifTrue: [self genSmallFloatArithmetic: SubRdRd preOpCheck: nil]<br>
ifFalse: [self genPureSmallFloatArithmetic: SubRdRd preOpCheck: nil]!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentation>>genPureDoubleComparison: (in category 'primitive generators') -----<br>
+ genPureDoubleComparison: jumpOpcodeGenerator<br>
+ "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
+ <option: #DPFPReg0><br>
+ <var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'><br>
+ | jumpFail jumpImmediate jumpCond compare |<br>
+ <var: #jumpImmediate type: #'AbstractInstruction *'><br>
+ <var: #jumpCond type: #'AbstractInstruction *'><br>
+ <var: #compare type: #'AbstractInstruction *'><br>
+ <var: #jumpFail type: #'AbstractInstruction *'><br>
+ cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:<br>
+ [^UnimplementedPrimitive].<br>
+ cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
+ self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.<br>
+ jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
+ self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
+ self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
+ jumpFail := cogit JumpNonZero: 0.<br>
+ self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
+ compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
+ cogit genPrimReturn.<br>
+ jumpImmediate jmpTarget: cogit Label.<br>
+ self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.<br>
+ jumpFail jmpTarget: cogit Label.<br>
+ ^CompletePrimitive!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentation>>genPureDoubleComparison:invert: (in category 'primitive generators') -----<br>
- genPureDoubleComparison: jumpOpcodeGenerator invert: invertComparison<br>
- "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
- <option: #DPFPReg0><br>
- <var: #jumpOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpOpcodeGenerator)(void *)'><br>
- | jumpFail jumpImmediate jumpCond compare |<br>
- <var: #jumpImmediate type: #'AbstractInstruction *'><br>
- <var: #jumpCond type: #'AbstractInstruction *'><br>
- <var: #compare type: #'AbstractInstruction *'><br>
- <var: #jumpFail type: #'AbstractInstruction *'><br>
- cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:<br>
- [^UnimplementedPrimitive].<br>
- cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
- self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.<br>
- jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
- self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
- self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
- jumpFail := cogit JumpNonZero: 0.<br>
- self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
- invertComparison "May need to invert for NaNs"<br>
- ifTrue: [compare := cogit CmpRd: DPFPReg0 Rd: DPFPReg1]<br>
- ifFalse: [compare := cogit CmpRd: DPFPReg1 Rd: DPFPReg0].<br>
- jumpCond := cogit perform: jumpOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
- cogit genPrimReturn.<br>
- jumpImmediate jmpTarget: cogit Label.<br>
- self maybeGenConvertIfSmallFloatIn: Arg0Reg scratchReg: TempReg into: DPFPReg1 andJumpTo: compare.<br>
- jumpFail jmpTarget: cogit Label.<br>
- ^CompletePrimitive!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentation>>genSmallIntegerComparison:orDoubleComparison: (in category 'primitive generators') -----<br>
+ genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator<br>
+ "Stack looks like<br>
+ return address"<br>
+ | jumpNonInt jumpFail jumpCond r |<br>
+ <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'><br>
+ <var: #jumpNonInt type: #'AbstractInstruction *'><br>
+ <var: #jumpCond type: #'AbstractInstruction *'><br>
+ <var: #jumpFail type: #'AbstractInstruction *'><br>
+ r := self genSmallIntegerComparison: jumpOpcode.<br>
+ r < 0 ifTrue:<br>
+ [^r].<br>
+ self cppIf: #DPFPReg0 defined ifTrue:<br>
+ "Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail"<br>
+ [self smallIntegerIsOnlyImmediateType ifFalse:<br>
+ [jumpNonInt := self genJumpImmediate: Arg0Reg].<br>
+ self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
+ self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
+ jumpFail := cogit JumpNonZero: 0.<br>
+ <br>
+ "It was a Float, so convert the receiver to double and perform the operation"<br>
+ self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.<br>
+ cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.<br>
+ self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
+ cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
+ cogit genPrimReturn.<br>
+ <br>
+ self smallIntegerIsOnlyImmediateType<br>
+ ifTrue: [jumpFail jmpTarget: cogit Label]<br>
+ ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: cogit Label)]].<br>
+ ^CompletePrimitive!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentation>>genSmallIntegerComparison:orDoubleComparison:invert: (in category 'primitive generators') -----<br>
- genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator invert: invertComparison<br>
- "Stack looks like<br>
- return address"<br>
- | jumpNonInt jumpFail jumpCond r |<br>
- <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'><br>
- <var: #jumpNonInt type: #'AbstractInstruction *'><br>
- <var: #jumpCond type: #'AbstractInstruction *'><br>
- <var: #jumpFail type: #'AbstractInstruction *'><br>
- r := self genSmallIntegerComparison: jumpOpcode.<br>
- r < 0 ifTrue:<br>
- [^r].<br>
- self cppIf: #DPFPReg0 defined ifTrue:<br>
- "Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail"<br>
- [self smallIntegerIsOnlyImmediateType ifFalse:<br>
- [jumpNonInt := self genJumpImmediate: Arg0Reg].<br>
- self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
- self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
- jumpFail := cogit JumpNonZero: 0.<br>
- <br>
- "It was a Float, so convert the receiver to double and perform the operation"<br>
- self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.<br>
- cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.<br>
- self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
- invertComparison "May need to invert for NaNs"<br>
- ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]<br>
- ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].<br>
- jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
- cogit genPrimReturn.<br>
- <br>
- self smallIntegerIsOnlyImmediateType<br>
- ifTrue: [jumpFail jmpTarget: cogit Label]<br>
- ifFalse: [jumpNonInt jmpTarget: (jumpFail jmpTarget: cogit Label)]].<br>
- ^CompletePrimitive!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genDoubleComparison:orIntegerComparison: (in category 'primitive generators') -----<br>
+ genDoubleComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode<br>
+ <inline: true><br>
+ ^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode boxed: true!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genDoubleComparison:orIntegerComparison:invert: (in category 'primitive generators') -----<br>
- genDoubleComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison<br>
- <inline: true><br>
- ^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison boxed: true!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genFloatComparison:orIntegerComparison:boxed: (in category 'primitive generators') -----<br>
+ genFloatComparison: jumpFPOpcodeGenerator orIntegerComparison: jumpOpcode boxed: rcvrBoxed<br>
+ <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'><br>
+ <inline: false><br>
+ | jumpImmediate jumpNotSmallFloat jumpNotSmallInteger jumpNotBoxedFloat jumpCond compareFloat jumpNotAmbiguous jumpTrue returnTrue |<br>
+ <var: #jumpNotSmallInteger type: #'AbstractInstruction *'><br>
+ <var: #jumpNotBoxedFloat type: #'AbstractInstruction *'><br>
+ <var: #jumpNotSmallFloat type: #'AbstractInstruction *'><br>
+ <var: #jumpImmediate type: #'AbstractInstruction *'><br>
+ <var: #jumpNotAmbiguous type: #'AbstractInstruction *'><br>
+ <var: #jumpCond type: #'AbstractInstruction *'><br>
+ <var: #jumpTrue type: #'AbstractInstruction *'><br>
+ <var: #returnTrue type: #'AbstractInstruction *'><br>
+ <var: #compareFloat type: #'AbstractInstruction *'><br>
+ cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
+ rcvrBoxed<br>
+ ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]<br>
+ ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].<br>
+ jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.<br>
+ self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.<br>
+ compareFloat := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).<br>
+ cogit genPrimReturn.<br>
+ <br>
+ jumpNotSmallFloat jmpTarget: cogit Label.<br>
+ jumpNotSmallInteger := self genJumpNotSmallInteger: Arg0Reg.<br>
+ "Test for ambiguity, that is when floatRcvr == (double) intArg"<br>
+ self genConvertSmallIntegerToIntegerInReg: Arg0Reg.<br>
+ cogit ConvertR: Arg0Reg Rd: DPFPReg1.<br>
+ cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ "If floatRcvr !!= (double) intArg then use compareFloat(floatRcvr,(double) intArg)"<br>
+ "else use compareInt(intArg,(int64) floatRcvr)"<br>
+ jumpNotAmbiguous := cogit perform: #JumpFPNotEqual: with: 0.<br>
+ "Case of non ambiguity, use compareFloat(floatRcvr,(double) intArg)"<br>
+ jumpNotAmbiguous jmpTarget: compareFloat.<br>
+ "Case of ambiguity, use compareInt((int64) floatRcvr, intArg)"<br>
+ cogit ConvertRd: DPFPReg0 R: ReceiverResultReg.<br>
+ cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"<br>
+ jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpTrue jmpTarget: returnTrue.<br>
+ <br>
+ "not a Small Float, nor Small Integer, check for Boxed Float argument"<br>
+ jumpNotSmallInteger jmpTarget: cogit Label.<br>
+ jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
+ self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
+ self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
+ jumpNotBoxedFloat := cogit JumpNonZero: 0.<br>
+ self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
+ cogit Jump: compareFloat.<br>
+ <br>
+ jumpImmediate jmpTarget:<br>
+ (jumpNotBoxedFloat jmpTarget: cogit Label).<br>
+ ^CompletePrimitive!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genFloatComparison:orIntegerComparison:invert:boxed: (in category 'primitive generators') -----<br>
- genFloatComparison: jumpFPOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison boxed: rcvrBoxed<br>
- <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'><br>
- <inline: false><br>
- | jumpImmediate jumpNotSmallFloat jumpNotSmallInteger jumpNotBoxedFloat jumpCond compareFloat jumpAmbiguous jumpTrue returnTrue |<br>
- <var: #jumpNotSmallInteger type: #'AbstractInstruction *'><br>
- <var: #jumpNotBoxedFloat type: #'AbstractInstruction *'><br>
- <var: #jumpNotSmallFloat type: #'AbstractInstruction *'><br>
- <var: #jumpImmediate type: #'AbstractInstruction *'><br>
- <var: #jumpAmbiguous type: #'AbstractInstruction *'><br>
- <var: #jumpCond type: #'AbstractInstruction *'><br>
- <var: #jumpTrue type: #'AbstractInstruction *'><br>
- <var: #returnTrue type: #'AbstractInstruction *'><br>
- <var: #compareFloat type: #'AbstractInstruction *'><br>
- cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
- rcvrBoxed<br>
- ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]<br>
- ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].<br>
- jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.<br>
- self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.<br>
- compareFloat := invertComparison "May need to invert for NaNs"<br>
- ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]<br>
- ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].<br>
- jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).<br>
- cogit genPrimReturn.<br>
- <br>
- jumpNotSmallFloat jmpTarget: cogit Label.<br>
- jumpNotSmallInteger := self genJumpNotSmallInteger: Arg0Reg.<br>
- "Test for ambiguity, that is when floatRcvr == (double) intArg"<br>
- self genConvertSmallIntegerToIntegerInReg: Arg0Reg.<br>
- cogit ConvertR: Arg0Reg Rd: DPFPReg1.<br>
- cogit CmpRd: DPFPReg0 Rd: DPFPReg1.<br>
- "If floatRcvr == (double) intArg then use compareInt(intArg,(int64) floatRcvr)"<br>
- "else use compareFloat(floatRcvr,(double) intArg)"<br>
- jumpAmbiguous := cogit perform: #JumpFPEqual: with: 0.<br>
- "Case of non ambiguity, use compareFloat(floatRcvr,(double) intArg)"<br>
- cogit Jump: compareFloat.<br>
- "Case of ambiguity, use compareInt((int64) floatRcvr, intArg)"<br>
- jumpAmbiguous jmpTarget: (cogit ConvertRd: DPFPReg0 R: ReceiverResultReg).<br>
- cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"<br>
- jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpTrue jmpTarget: returnTrue.<br>
- <br>
- "not a Small Float, nor Small Integer, check for Boxed Float argument"<br>
- jumpNotSmallInteger jmpTarget: cogit Label.<br>
- jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
- self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
- self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
- jumpNotBoxedFloat := cogit JumpNonZero: 0.<br>
- self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
- cogit Jump: compareFloat.<br>
- <br>
- jumpImmediate jmpTarget:<br>
- (jumpNotBoxedFloat jmpTarget: cogit Label).<br>
- ^CompletePrimitive!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatGreaterOrEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----<br>
genPrimitiveFloatGreaterThan<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPGreater:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatLessOrEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPLessOrEqual: orIntegerComparison: JumpLessOrEqual]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPLessOrEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessThan (in category 'primitive generators') -----<br>
genPrimitiveFloatLessThan<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPLess: orIntegerComparison: JumpLess]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPLess:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!<br>
<br>
Item was changed:<br>
----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----<br>
genPrimitiveFloatNotEqual<br>
<option: #DPFPReg0><br>
+ ^coInterpreter getPrimitiveDoMixedArithmetic<br>
+ ifTrue: [self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero]<br>
+ ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual:]!<br>
- ^self getPrimitiveDoMixedArithmetic<br>
- ifTrue: [self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]<br>
- ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureDoubleComparison: (in category 'primitive generators') -----<br>
+ genPureDoubleComparison: jumpOpcodeGenerator<br>
+ "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
+ <inline: true><br>
+ ^self genPureFloatComparison: jumpOpcodeGenerator boxed: true!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPureDoubleComparison:invert: (in category 'primitive generators') -----<br>
- genPureDoubleComparison: jumpOpcodeGenerator invert: invertComparison<br>
- "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
- <inline: true><br>
- ^self genPureFloatComparison: jumpOpcodeGenerator invert: invertComparison boxed: true!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureFloatComparison:boxed: (in category 'primitive generators') -----<br>
+ genPureFloatComparison: jumpFPOpcodeGenerator boxed: rcvrBoxed<br>
+ "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
+ <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'><br>
+ <inline: false><br>
+ | jumpImmediate jumpNotSmallFloat jumpNotBoxedFloat jumpCond compareFloat |<br>
+ <var: #jumpNotBoxedFloat type: #'AbstractInstruction *'><br>
+ <var: #jumpNotSmallFloat type: #'AbstractInstruction *'><br>
+ <var: #jumpImmediate type: #'AbstractInstruction *'><br>
+ <var: #jumpCond type: #'AbstractInstruction *'><br>
+ <var: #compareFloat type: #'AbstractInstruction *'><br>
+ cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
+ rcvrBoxed<br>
+ ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]<br>
+ ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].<br>
+ jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.<br>
+ self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.<br>
+ compareFloat := cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
+ cogit genPrimReturn.<br>
+ <br>
+ "not a Small Float, check for Boxed Float argument"<br>
+ jumpNotSmallFloat jmpTarget: cogit Label.<br>
+ jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
+ self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
+ self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
+ jumpNotBoxedFloat := cogit JumpNonZero: 0.<br>
+ self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
+ cogit Jump: compareFloat.<br>
+ <br>
+ jumpImmediate jmpTarget:<br>
+ (jumpNotBoxedFloat jmpTarget: cogit Label).<br>
+ ^CompletePrimitive!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPureFloatComparison:invert:boxed: (in category 'primitive generators') -----<br>
- genPureFloatComparison: jumpFPOpcodeGenerator invert: invertComparison boxed: rcvrBoxed<br>
- "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
- <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction *(*jumpFPOpcodeGenerator)(void *)'><br>
- <inline: false><br>
- | jumpImmediate jumpNotSmallFloat jumpNotBoxedFloat jumpCond compareFloat |<br>
- <var: #jumpNotBoxedFloat type: #'AbstractInstruction *'><br>
- <var: #jumpNotSmallFloat type: #'AbstractInstruction *'><br>
- <var: #jumpImmediate type: #'AbstractInstruction *'><br>
- <var: #jumpCond type: #'AbstractInstruction *'><br>
- <var: #compareFloat type: #'AbstractInstruction *'><br>
- cogit genLoadArgAtDepth: 0 into: Arg0Reg.<br>
- rcvrBoxed<br>
- ifTrue: [self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0]<br>
- ifFalse: [self genGetSmallFloatValueOf: ReceiverResultReg scratch: TempReg into: DPFPReg0].<br>
- jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.<br>
- self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.<br>
- compareFloat := invertComparison "May need to invert for NaNs"<br>
- ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]<br>
- ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].<br>
- jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpCond jmpTarget: (cogit genMoveTrueR: ReceiverResultReg).<br>
- cogit genPrimReturn.<br>
- <br>
- "not a Small Float, check for Boxed Float argument"<br>
- jumpNotSmallFloat jmpTarget: cogit Label.<br>
- jumpImmediate := self genJumpImmediate: Arg0Reg.<br>
- self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
- self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
- jumpNotBoxedFloat := cogit JumpNonZero: 0.<br>
- self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
- cogit Jump: compareFloat.<br>
- <br>
- jumpImmediate jmpTarget:<br>
- (jumpNotBoxedFloat jmpTarget: cogit Label).<br>
- ^CompletePrimitive!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genPureSmallFloatComparison: (in category 'primitive generators') -----<br>
+ genPureSmallFloatComparison: jumpOpcodeGenerator<br>
+ "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
+ <inline: true><br>
+ ^self genPureFloatComparison: jumpOpcodeGenerator boxed: false!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genPureSmallFloatComparison:invert: (in category 'primitive generators') -----<br>
- genPureSmallFloatComparison: jumpOpcodeGenerator invert: invertComparison<br>
- "In the Pure version, mixed arithmetic with SmallInteger is forbidden"<br>
- <inline: true><br>
- ^self genPureFloatComparison: jumpOpcodeGenerator invert: invertComparison boxed: false!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallFloatComparison:orIntegerComparison: (in category 'primitive generators') -----<br>
+ genSmallFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode<br>
+ <inline: true><br>
+ ^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode boxed: false!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallFloatComparison:orIntegerComparison:invert: (in category 'primitive generators') -----<br>
- genSmallFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison<br>
- <inline: true><br>
- ^self genFloatComparison: jumpOpcodeGenerator orIntegerComparison: jumpOpcode invert: invertComparison boxed: false!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallIntegerComparison:orDoubleComparison: (in category 'primitive generators') -----<br>
+ genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator<br>
+ "Stack looks like<br>
+ return address"<br>
+ | jumpCond r compareIntFloat jumpAmbiguous jumpNotBoxedFloat jumpNotFloatAtAll jumpNotSmallFloat jumpTrue returnTrue |<br>
+ <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'><br>
+ <var: #jumpNonInt type: #'AbstractInstruction *'><br>
+ <var: #jumpCond type: #'AbstractInstruction *'><br>
+ <var: #jumpTrue type: #'AbstractInstruction *'><br>
+ <var: #returnTrue type: #'AbstractInstruction *'><br>
+ <var: #jumpAmbiguous type: #'AbstractInstruction *'><br>
+ <var: #jumpNotBoxedFloat type: #'AbstractInstruction *'><br>
+ <var: #jumpNotSmallFloat type: #'AbstractInstruction *'><br>
+ <var: #jumpNotFloatAtAll type: #'AbstractInstruction *'><br>
+ <var: #compareIntFloat type: #'AbstractInstruction *'><br>
+ r := self genSmallIntegerComparison: jumpOpcode.<br>
+ r < 0 ifTrue:<br>
+ [^r].<br>
+ self cppIf: #DPFPReg0 defined ifTrue:<br>
+ "Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail"<br>
+ [<br>
+ "check for Small Float argument"<br>
+ jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.<br>
+ self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.<br>
+ <br>
+ "Case of (int compare: float). Test for ambiguity, that is when (double) intRcvr == floatArg"<br>
+ compareIntFloat := cogit Label.<br>
+ self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.<br>
+ cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.<br>
+ cogit CmpRd: DPFPReg0 Rd: DPFPReg1.<br>
+ jumpAmbiguous := cogit perform: #JumpFPEqual: with: 0.<br>
+ "Case of non ambiguity, use compareFloat((double) intRcvr,floatArg)"<br>
+ cogit CmpRd: DPFPReg1 Rd: DPFPReg0.<br>
+ jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).<br>
+ cogit genPrimReturn.<br>
+ "Case of ambiguity, use compareInt(intRcvr , (int64) floatArg)"<br>
+ jumpAmbiguous jmpTarget: (cogit ConvertRd: DPFPReg1 R: Arg0Reg).<br>
+ cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"<br>
+ jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.<br>
+ cogit genMoveFalseR: ReceiverResultReg.<br>
+ cogit genPrimReturn.<br>
+ jumpTrue jmpTarget: returnTrue.<br>
+ <br>
+ "not a Small Float, check for Boxed Float argument"<br>
+ jumpNotSmallFloat jmpTarget: (jumpNotFloatAtAll := self genJumpImmediate: Arg0Reg).<br>
+ self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
+ self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
+ jumpNotBoxedFloat := cogit JumpNonZero: 0.<br>
+ "It was a Boxed Float, so convert the receiver to double and perform the (int compare: float) operation"<br>
+ self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
+ cogit Jump: compareIntFloat.<br>
+ <br>
+ "not a Float, just let the primitive fall thru failure"<br>
+ jumpNotBoxedFloat jmpTarget: (jumpNotFloatAtAll jmpTarget: cogit Label)].<br>
+ ^CompletePrimitive!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor64BitSpur>>genSmallIntegerComparison:orDoubleComparison:invert: (in category 'primitive generators') -----<br>
- genSmallIntegerComparison: jumpOpcode orDoubleComparison: jumpFPOpcodeGenerator invert: invertComparison<br>
- "Stack looks like<br>
- return address"<br>
- | jumpCond r compareIntFloat jumpAmbiguous jumpNotBoxedFloat jumpNotFloatAtAll jumpNotSmallFloat jumpTrue returnTrue |<br>
- <var: #jumpFPOpcodeGenerator declareC: 'AbstractInstruction * NoDbgRegParms (*jumpFPOpcodeGenerator)(void *)'><br>
- <var: #jumpNonInt type: #'AbstractInstruction *'><br>
- <var: #jumpCond type: #'AbstractInstruction *'><br>
- <var: #jumpTrue type: #'AbstractInstruction *'><br>
- <var: #returnTrue type: #'AbstractInstruction *'><br>
- <var: #jumpAmbiguous type: #'AbstractInstruction *'><br>
- <var: #jumpNotBoxedFloat type: #'AbstractInstruction *'><br>
- <var: #jumpNotSmallFloat type: #'AbstractInstruction *'><br>
- <var: #jumpNotFloatAtAll type: #'AbstractInstruction *'><br>
- <var: #compareIntFloat type: #'AbstractInstruction *'><br>
- r := self genSmallIntegerComparison: jumpOpcode.<br>
- r < 0 ifTrue:<br>
- [^r].<br>
- self cppIf: #DPFPReg0 defined ifTrue:<br>
- "Fall through on non-SmallInteger argument. Argument may be a Float : let us check or fail"<br>
- [<br>
- "check for Small Float argument"<br>
- jumpNotSmallFloat := self genJumpNotSmallFloat: Arg0Reg.<br>
- self genGetSmallFloatValueOf: Arg0Reg scratch: TempReg into: DPFPReg1.<br>
- <br>
- "Case of (int compare: float). Test for ambiguity, that is when (double) intRcvr == floatArg"<br>
- compareIntFloat := cogit Label.<br>
- self genConvertSmallIntegerToIntegerInReg: ReceiverResultReg.<br>
- cogit ConvertR: ReceiverResultReg Rd: DPFPReg0.<br>
- cogit CmpRd: DPFPReg0 Rd: DPFPReg1.<br>
- jumpAmbiguous := cogit perform: #JumpFPEqual: with: 0.<br>
- "Case of non ambiguity, use compareFloat((double) intRcvr,floatArg)"<br>
- invertComparison "May need to invert for NaNs"<br>
- ifTrue: [cogit CmpRd: DPFPReg0 Rd: DPFPReg1]<br>
- ifFalse: [cogit CmpRd: DPFPReg1 Rd: DPFPReg0].<br>
- jumpCond := cogit perform: jumpFPOpcodeGenerator with: 0. "FP jumps are a little weird"<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpCond jmpTarget: (returnTrue := cogit genMoveTrueR: ReceiverResultReg).<br>
- cogit genPrimReturn.<br>
- "Case of ambiguity, use compareInt(intRcvr , (int64) floatArg)"<br>
- jumpAmbiguous jmpTarget: (cogit ConvertRd: DPFPReg1 R: Arg0Reg).<br>
- cogit CmpR: Arg0Reg R: ReceiverResultReg. "N.B. FLAGS := RRReg - Arg0Reg"<br>
- jumpTrue := cogit genConditionalBranch: jumpOpcode operand: 0.<br>
- cogit genMoveFalseR: ReceiverResultReg.<br>
- cogit genPrimReturn.<br>
- jumpTrue jmpTarget: returnTrue.<br>
- <br>
- "not a Small Float, check for Boxed Float argument"<br>
- jumpNotSmallFloat jmpTarget: (jumpNotFloatAtAll := self genJumpImmediate: Arg0Reg).<br>
- self genGetCompactClassIndexNonImmOf: Arg0Reg into: SendNumArgsReg.<br>
- self genCmpClassFloatCompactIndexR: SendNumArgsReg.<br>
- jumpNotBoxedFloat := cogit JumpNonZero: 0.<br>
- "It was a Boxed Float, so convert the receiver to double and perform the (int compare: float) operation"<br>
- self genGetDoubleValueOf: Arg0Reg into: DPFPReg1.<br>
- cogit Jump: compareIntFloat.<br>
- <br>
- "not a Float, just let the primitive fall thru failure"<br>
- jumpNotBoxedFloat jmpTarget: (jumpNotFloatAtAll jmpTarget: cogit Label)].<br>
- ^CompletePrimitive!<br>
<br>
Item was changed:<br>
----- Method: CogX64Compiler>>generateCheckLZCNT (in category 'feature detection') -----<br>
generateCheckLZCNT<br>
"to check is Leading Zero Count operation is present<br>
cf. MSVC builtin __lzcnt documentation<br>
The result will be in bit 5 of return value (in RAX)"<br>
cogit<br>
PushR: RDX;<br>
PushR: RCX;<br>
PushR: RBX;<br>
+ MoveCq: 16r80000001 R: RAX;<br>
- MoveCw: 16r80000001 R: RAX;<br>
gen: CPUID;<br>
MoveR: RCX R: RAX;<br>
PopR: RBX;<br>
PopR: RCX;<br>
PopR: RDX;<br>
RetN: 0!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveSmallFloatEqual (in category 'arithmetic float primitives') -----<br>
primitiveSmallFloatEqual<br>
<option: #Spur64BitMemoryManager><br>
| rcvr arg intArg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).<br>
arg := objectMemory loadFloatOrIntFrom: self stackTop.<br>
self successful ifTrue:<br>
[self cppIf: objectMemory wordSize > 4<br>
+ ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])<br>
- ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ intArg := objectMemory integerValueOf: self stackTop.<br>
- intArg := self integerValueOf: self stackTop.<br>
self pop: 2 thenPushBool: rcvr asInteger = intArg]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr = arg]]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr = arg]]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveSmallFloatGreaterOrEqual (in category 'arithmetic float primitives') -----<br>
primitiveSmallFloatGreaterOrEqual<br>
<option: #Spur64BitMemoryManager><br>
| rcvr arg intArg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).<br>
arg := objectMemory loadFloatOrIntFrom: self stackTop.<br>
self successful ifTrue:<br>
[self cppIf: objectMemory wordSize > 4<br>
+ ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])<br>
- ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ intArg := objectMemory integerValueOf: self stackTop.<br>
- intArg := self integerValueOf: self stackTop.<br>
self pop: 2 thenPushBool: rcvr asInteger >= intArg]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr >= arg]]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr >= arg]]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveSmallFloatGreaterThan (in category 'arithmetic float primitives') -----<br>
primitiveSmallFloatGreaterThan<br>
<option: #Spur64BitMemoryManager><br>
| rcvr arg intArg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).<br>
arg := objectMemory loadFloatOrIntFrom: self stackTop.<br>
self successful ifTrue:<br>
[self cppIf: objectMemory wordSize > 4<br>
+ ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])<br>
- ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ intArg := objectMemory integerValueOf: self stackTop.<br>
- intArg := self integerValueOf: self stackTop.<br>
self pop: 2 thenPushBool: rcvr asInteger > intArg]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr > arg]]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr > arg]]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveSmallFloatLessOrEqual (in category 'arithmetic float primitives') -----<br>
primitiveSmallFloatLessOrEqual<br>
<option: #Spur64BitMemoryManager><br>
| rcvr arg intArg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).<br>
arg := objectMemory loadFloatOrIntFrom: self stackTop.<br>
self successful ifTrue:<br>
[self cppIf: objectMemory wordSize > 4<br>
+ ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])<br>
- ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ intArg := objectMemory integerValueOf: self stackTop.<br>
- intArg := self integerValueOf: self stackTop.<br>
self pop: 2 thenPushBool: rcvr asInteger <= intArg]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr <= arg]]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr <= arg]]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveSmallFloatLessThan (in category 'arithmetic float primitives') -----<br>
primitiveSmallFloatLessThan<br>
<option: #Spur64BitMemoryManager><br>
| rcvr arg intArg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).<br>
arg := objectMemory loadFloatOrIntFrom: self stackTop.<br>
self successful ifTrue:<br>
[self cppIf: objectMemory wordSize > 4<br>
+ ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])<br>
- ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ intArg := objectMemory integerValueOf: self stackTop.<br>
- intArg := self integerValueOf: self stackTop.<br>
self pop: 2 thenPushBool: rcvr asInteger < intArg]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr < arg]]<br>
ifFalse: [self pop: 2 thenPushBool: rcvr < arg]]!<br>
<br>
Item was changed:<br>
----- Method: InterpreterPrimitives>>primitiveSmallFloatNotEqual (in category 'arithmetic float primitives') -----<br>
primitiveSmallFloatNotEqual<br>
<option: #Spur64BitMemoryManager><br>
| rcvr arg intArg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).<br>
arg := objectMemory loadFloatOrIntFrom: self stackTop.<br>
self successful ifTrue:<br>
[self cppIf: objectMemory wordSize > 4<br>
+ ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])<br>
- ifTrue: [((self isIntegerObject: self stackTop) and: [rcvr = arg])<br>
ifTrue: ["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ intArg := objectMemory integerValueOf: self stackTop.<br>
- intArg := self integerValueOf: self stackTop.<br>
self pop: 2 thenPushBool: (rcvr asInteger = intArg) not]<br>
ifFalse: [self pop: 2 thenPushBool: (rcvr = arg) not]]<br>
ifFalse: [self pop: 2 thenPushBool: (rcvr = arg) not]]!<br>
<br>
Item was changed:<br>
----- Method: Spur64BitMemoryManager>>loadFloatOrIntFrom: (in category 'interpreter access') -----<br>
loadFloatOrIntFrom: floatOrIntOop<br>
"If floatOrInt is an integer and we enable mixed arithmetic in primitives, then convert it to a C double float and return it.<br>
If it is a Float, then load its value and return it.<br>
Otherwise fail -- ie return with primErrorCode non-zero."<br>
<br>
<inline: true><br>
<returnTypeC: #double><br>
| result tagBits |<br>
<var: #result type: #double><br>
<br>
(tagBits := floatOrIntOop bitAnd: self tagMask) ~= 0<br>
ifTrue:<br>
[tagBits = self smallFloatTag ifTrue:<br>
[^self smallFloatValueOf: floatOrIntOop].<br>
+ (coInterpreter primitiveDoMixedArithmetic and: [tagBits = self smallIntegerTag]) ifTrue:<br>
- (self primitiveDoMixedArithmetic and: [tagBits = self smallIntegerTag]) ifTrue:<br>
[^(self integerValueOf: floatOrIntOop) asFloat]]<br>
ifFalse:<br>
[(self classIndexOf: floatOrIntOop) = ClassFloatCompactIndex ifTrue:<br>
[self cCode: '' inSmalltalk: [result := Float new: 2].<br>
self fetchFloatAt: floatOrIntOop + self baseHeaderSize into: result.<br>
^result]].<br>
coInterpreter primitiveFail.<br>
^0.0!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>primitiveFloatEqual:toArg: (in category 'comparison float primitives') -----<br>
primitiveFloatEqual: rcvrOop toArg: argOop<br>
| rcvr arg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.<br>
arg := objectMemory loadFloatOrIntFrom: argOop.<br>
self cppIf: objectMemory wordSize > 4<br>
ifTrue: [rcvr = arg<br>
ifTrue:<br>
+ [(objectMemory isIntegerObject: argOop)<br>
- [(self isIntegerObject: argOop)<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ ^ rcvr asInteger = (objectMemory integerValueOf: argOop)]<br>
+ ifFalse: [(objectMemory isIntegerObject: rcvrOop)<br>
- ^ rcvr asInteger = (self integerValueOf: argOop)]<br>
- ifFalse: [(self isIntegerObject: rcvrOop)<br>
ifTrue:<br>
["Same when used from bytecodePrim...<br>
note that rcvr and arg cannot be both integer (case is already handled)"<br>
+ ^ (objectMemory integerValueOf: rcvrOop) = arg asInteger]]]].<br>
- ^ (self integerValueOf: rcvrOop) = arg asInteger]]]].<br>
^rcvr = arg!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>primitiveFloatGreater:thanArg: (in category 'comparison float primitives') -----<br>
primitiveFloatGreater: rcvrOop thanArg: argOop<br>
| rcvr arg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.<br>
arg := objectMemory loadFloatOrIntFrom: argOop.<br>
self cppIf: objectMemory wordSize > 4<br>
ifTrue: [rcvr = arg<br>
ifTrue:<br>
+ [(objectMemory isIntegerObject: argOop)<br>
- [(self isIntegerObject: argOop)<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ ^ rcvr asInteger > (objectMemory integerValueOf: argOop)]<br>
+ ifFalse: [(objectMemory isIntegerObject: rcvrOop)<br>
- ^ rcvr asInteger > (self integerValueOf: argOop)]<br>
- ifFalse: [(self isIntegerObject: rcvrOop)<br>
ifTrue:<br>
["Same when used from bytecodePrim...<br>
note that rcvr and arg cannot be both integer (case is already handled)"<br>
+ ^ (objectMemory integerValueOf: rcvrOop) > arg asInteger]]]].<br>
- ^ (self integerValueOf: rcvrOop) > arg asInteger]]]].<br>
^rcvr > arg!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>primitiveFloatGreaterOrEqual:toArg: (in category 'comparison float primitives') -----<br>
primitiveFloatGreaterOrEqual: rcvrOop toArg: argOop<br>
| rcvr arg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.<br>
arg := objectMemory loadFloatOrIntFrom: argOop.<br>
self cppIf: objectMemory wordSize > 4<br>
ifTrue: [rcvr = arg<br>
ifTrue:<br>
+ [(objectMemory isIntegerObject: argOop)<br>
- [(self isIntegerObject: argOop)<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ ^ rcvr asInteger >= (objectMemory integerValueOf: argOop)]<br>
+ ifFalse: [(objectMemory isIntegerObject: rcvrOop)<br>
- ^ rcvr asInteger >= (self integerValueOf: argOop)]<br>
- ifFalse: [(self isIntegerObject: rcvrOop)<br>
ifTrue:<br>
["Same when used from bytecodePrim...<br>
note that rcvr and arg cannot be both integer (case is already handled)"<br>
+ ^ (objectMemory integerValueOf: rcvrOop) >= arg asInteger]]]].<br>
- ^ (self integerValueOf: rcvrOop) >= arg asInteger]]]].<br>
^rcvr >= arg!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>primitiveFloatLess:thanArg: (in category 'comparison float primitives') -----<br>
primitiveFloatLess: rcvrOop thanArg: argOop<br>
| rcvr arg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.<br>
arg := objectMemory loadFloatOrIntFrom: argOop.<br>
self cppIf: objectMemory wordSize > 4<br>
ifTrue: [rcvr = arg<br>
ifTrue:<br>
+ [(objectMemory isIntegerObject: argOop)<br>
- [(self isIntegerObject: argOop)<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ ^ rcvr asInteger < (objectMemory integerValueOf: argOop)]<br>
+ ifFalse: [(objectMemory isIntegerObject: rcvrOop)<br>
- ^ rcvr asInteger < (self integerValueOf: argOop)]<br>
- ifFalse: [(self isIntegerObject: rcvrOop)<br>
ifTrue:<br>
["Same when used from bytecodePrim...<br>
note that rcvr and arg cannot be both integer (case is already handled)"<br>
+ ^ (objectMemory integerValueOf: rcvrOop) < arg asInteger]]]].<br>
- ^ (self integerValueOf: rcvrOop) < arg asInteger]]]].<br>
^rcvr < arg!<br>
<br>
Item was changed:<br>
----- Method: StackInterpreter>>primitiveFloatLessOrEqual:toArg: (in category 'comparison float primitives') -----<br>
primitiveFloatLessOrEqual: rcvrOop toArg: argOop<br>
| rcvr arg |<br>
<var: #rcvr type: #double><br>
<var: #arg type: #double><br>
<br>
rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.<br>
arg := objectMemory loadFloatOrIntFrom: argOop.<br>
self cppIf: objectMemory wordSize > 4<br>
ifTrue: [rcvr = arg<br>
ifTrue:<br>
+ [(objectMemory isIntegerObject: argOop)<br>
- [(self isIntegerObject: argOop)<br>
ifTrue:<br>
["Resolve case of ambiguity so as to have comparison of exact values"<br>
+ ^ rcvr asInteger <= (objectMemory integerValueOf: argOop)]<br>
+ ifFalse: [(objectMemory isIntegerObject: rcvrOop)<br>
- ^ rcvr asInteger <= (self integerValueOf: argOop)]<br>
- ifFalse: [(self isIntegerObject: rcvrOop)<br>
ifTrue:<br>
["Same when used from bytecodePrim...<br>
note that rcvr and arg cannot be both integer (case is already handled)"<br>
+ ^ (objectMemory integerValueOf: rcvrOop) <= arg asInteger]]]].<br>
- ^ (self integerValueOf: rcvrOop) <= arg asInteger]]]].<br>
^rcvr <= arg!<br>
<br>
</blockquote></div>