[Vm-dev] VM Maker: VMMaker.oscog-nice.2557.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Sep 7 07:17:56 UTC 2019


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!



More information about the Vm-dev mailing list