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

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

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

commits-2
 
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!