Nicolas Cellier uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2557.mcz ==================== Summary ==================== Name: VMMaker.oscog-nice.2557 Author: nice Time: 7 September 2019, 9:16:52.820927 am UUID: 2e78205b-b7ec-4fc3-b020-a52223bbc156 Ancestors: VMMaker.oscog-eem.2556 Fix the genJumpFPLess: and genJumpFPLessOrEqual: on IA32 architectures so that they correctly answer false for a NaN operand. Refactor genJumpFPEqual: and genJumpFPNotEqual: to use similar paths. a NaN operand (unordered comparison) set the three flags ZF PF CF and generates false positives! See Smallissimo blog post How to JIT Float comparison on X64 in opensmalltalk-vm http://smallissimo.blogspot.com/2019/09/how-to-jit-float-comparison-on-x64-in.html or this synthetic SO question: Intel x86_64 assembly compare signed double precision floats https://stackoverflow.com/questions/37766131/intel-x86-64-assembly-compare-signed-double-precision-floats =============== Diff against VMMaker.oscog-eem.2556 =============== Item was changed: ----- Method: CogIA32Compiler>>genJumpFPEqual: (in category 'abstract instructions') ----- genJumpFPEqual: jumpTarget <inline: true> <returnTypeC: #'AbstractInstruction *'> <var: #jumpTarget type: #'void *'> + ^self genJumpFPOrderedAnd: JumpFPEqual to: jumpTarget! - | jumpUnordered jumpToTarget | - <var: #jumpUnordered type: #'AbstractInstruction *'> - <var: #jumpToTarget type: #'AbstractInstruction *'> - jumpUnordered := cogit gen: JumpFPUnordered. - jumpToTarget := cogit gen: JumpFPEqual operand: jumpTarget asInteger. - jumpUnordered jmpTarget: cogit Label. - ^jumpToTarget! Item was added: + ----- Method: CogIA32Compiler>>genJumpFPLess: (in category 'abstract instructions') ----- + genJumpFPLess: jumpTarget + "Note: this generates two jumps for handling case of NaN operands + Sender might prefer using a JumpFPGreater with swapped operands." + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + ^self genJumpFPOrderedAnd: JumpFPLess to: jumpTarget! Item was added: + ----- Method: CogIA32Compiler>>genJumpFPLessOrEqual: (in category 'abstract instructions') ----- + genJumpFPLessOrEqual: jumpTarget + "Note: this generates two jumps for handling case of NaN operands + Sender might prefer using a JumpFPGreaterOrEqual with swapped operands." + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + ^self genJumpFPOrderedAnd: JumpFPLessOrEqual to: jumpTarget! Item was changed: ----- Method: CogIA32Compiler>>genJumpFPNotEqual: (in category 'abstract instructions') ----- genJumpFPNotEqual: jumpTarget <inline: true> <returnTypeC: #'AbstractInstruction *'> <var: #jumpTarget type: #'void *'> + ^self genJumpFPUnorderedOr: JumpFPNotEqual to: jumpTarget! - | jumpUnordered jumpToTarget | - <var: #jumpUnordered type: #'AbstractInstruction *'> - <var: #jumpToTarget type: #'AbstractInstruction *'> - jumpToTarget := cogit gen: JumpFPNotEqual operand: jumpTarget asInteger. - jumpUnordered := cogit gen: JumpFPUnordered operand: jumpTarget asInteger. - jumpToTarget addDependent: jumpUnordered. - ^jumpToTarget! Item was added: + ----- Method: CogIA32Compiler>>genJumpFPOrderedAnd:to: (in category 'abstract instructions') ----- + genJumpFPOrderedAnd: jumpOpCode to: jumpTarget + "Test the comparison status flags ZF PF CF and jump to jumpTarget when + - both Ordered (no nan opearand) - a JNP + - and the other condition (determined by jumpOpCode) is true + jumpTarget maybe either an Integer offset, or an AbstractInstruction. + This is necessary on Intel IA32 for JB JBE and JE with nan operands, + otherwise unordered condition set the three flags to 1 and cause false positive. + The implementation use JP to jump over the over test + rather than link a JNP and jumpOpCode jumpTarget" + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + | jumpUnordered jumpToTarget | + <var: #jumpUnordered type: #'AbstractInstruction *'> + <var: #jumpToTarget type: #'AbstractInstruction *'> + jumpToTarget := cogit gen: jumpOpCode operand: jumpTarget asInteger. + jumpUnordered := cogit gen: JumpFPUnordered operand: jumpTarget asInteger. + jumpToTarget addDependent: jumpUnordered. + ^jumpToTarget! Item was added: + ----- Method: CogIA32Compiler>>genJumpFPUnorderedOr:to: (in category 'abstract instructions') ----- + genJumpFPUnorderedOr: jumpOpCode to: jumpTarget + "Test the comparison status flags ZF PF CF and jump to jumpTarget when + - either Unordered (no nan opearand) - a JP + - and the other condition (determined by jumpOpCode) is true + jumpTarget maybe either an Integer offset, or an AbstractInstruction. + This is necessary on Intel IA32 for JNE with nan operands, + otherwise unordered condition set the three flags to 1 and cause false negative." + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + | jumpUnordered jumpToTarget | + <var: #jumpUnordered type: #'AbstractInstruction *'> + <var: #jumpToTarget type: #'AbstractInstruction *'> + jumpToTarget := cogit gen: JumpFPNotEqual operand: jumpTarget asInteger. + jumpUnordered := cogit gen: JumpFPUnordered operand: jumpTarget asInteger. + jumpToTarget addDependent: jumpUnordered. + ^jumpToTarget! Item was changed: ----- Method: CogX64Compiler>>genJumpFPEqual: (in category 'abstract instructions') ----- genJumpFPEqual: jumpTarget <inline: true> <returnTypeC: #'AbstractInstruction *'> <var: #jumpTarget type: #'void *'> + ^self genJumpFPOrderedAnd: JumpFPEqual to: jumpTarget! - | jumpUnordered jumpToTarget | - <var: #jumpUnordered type: #'AbstractInstruction *'> - <var: #jumpToTarget type: #'AbstractInstruction *'> - jumpUnordered := cogit gen: JumpFPUnordered. - jumpToTarget := cogit gen: JumpFPEqual operand: jumpTarget asInteger. - jumpUnordered jmpTarget: cogit Label. - ^jumpToTarget! Item was added: + ----- Method: CogX64Compiler>>genJumpFPLess: (in category 'abstract instructions') ----- + genJumpFPLess: jumpTarget + "Note: this generates two jumps for handling case of NaN operands + Sender might prefer using a JumpFPGreater with swapped operands." + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + ^self genJumpFPOrderedAnd: JumpFPLess to: jumpTarget! Item was added: + ----- Method: CogX64Compiler>>genJumpFPLessOrEqual: (in category 'abstract instructions') ----- + genJumpFPLessOrEqual: jumpTarget + "Note: this generates two jumps for handling case of NaN operands + Sender might prefer using a JumpFPGreaterOrEqual with swapped operands." + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + ^self genJumpFPOrderedAnd: JumpFPLessOrEqual to: jumpTarget! Item was changed: ----- Method: CogX64Compiler>>genJumpFPNotEqual: (in category 'abstract instructions') ----- genJumpFPNotEqual: jumpTarget <inline: true> <returnTypeC: #'AbstractInstruction *'> <var: #jumpTarget type: #'void *'> + ^self genJumpFPUnorderedOr: JumpFPNotEqual to: jumpTarget! - | jumpUnordered jumpToTarget | - <var: #jumpUnordered type: #'AbstractInstruction *'> - <var: #jumpToTarget type: #'AbstractInstruction *'> - jumpToTarget := cogit gen: JumpFPNotEqual operand: jumpTarget asInteger. - jumpUnordered := cogit gen: JumpFPUnordered operand: jumpTarget asInteger. - jumpToTarget addDependent: jumpUnordered. - ^jumpToTarget! Item was added: + ----- Method: CogX64Compiler>>genJumpFPOrderedAnd:to: (in category 'abstract instructions') ----- + genJumpFPOrderedAnd: jumpOpCode to: jumpTarget + "Test the comparison status flags ZF PF CF and jump to jumpTarget when + - both Ordered (no nan opearand) - a JNP + - and the other condition (determined by jumpOpCode) is true + jumpTarget maybe either an Integer offset, or an AbstractInstruction. + This is necessary on Intel IA32 for JB JBE and JE with nan operands, + otherwise unordered condition set the three flags to 1 and cause false positive. + The implementation use JP to jump over the over test + rather than link a JNP and jumpOpCode jumpTarget" + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + | jumpUnordered jumpToTarget | + <var: #jumpUnordered type: #'AbstractInstruction *'> + <var: #jumpToTarget type: #'AbstractInstruction *'> + jumpToTarget := cogit gen: jumpOpCode operand: jumpTarget asInteger. + jumpUnordered := cogit gen: JumpFPUnordered operand: jumpTarget asInteger. + jumpToTarget addDependent: jumpUnordered. + ^jumpToTarget! Item was added: + ----- Method: CogX64Compiler>>genJumpFPUnorderedOr:to: (in category 'abstract instructions') ----- + genJumpFPUnorderedOr: jumpOpCode to: jumpTarget + "Test the comparison status flags ZF PF CF and jump to jumpTarget when + - either Unordered (no nan opearand) - a JP + - and the other condition (determined by jumpOpCode) is true + jumpTarget maybe either an Integer offset, or an AbstractInstruction. + This is necessary on Intel IA32 for JNE with nan operands, + otherwise unordered condition set the three flags to 1 and cause false negative." + <inline: true> + <returnTypeC: #'AbstractInstruction *'> + <var: #jumpTarget type: #'void *'> + | jumpUnordered jumpToTarget | + <var: #jumpUnordered type: #'AbstractInstruction *'> + <var: #jumpToTarget type: #'AbstractInstruction *'> + jumpToTarget := cogit gen: JumpFPNotEqual operand: jumpTarget asInteger. + jumpUnordered := cogit gen: JumpFPUnordered operand: jumpTarget asInteger. + jumpToTarget addDependent: jumpUnordered. + ^jumpToTarget! |
Free forum by Nabble | Edit this page |