VM Maker: VMMaker.oscog-nice.2553.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.2553.mcz

commits-2
 
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2553.mcz

==================== Summary ====================

Name: VMMaker.oscog-nice.2553
Author: nice
Time: 6 September 2019, 1:41:54.947306 am
UUID: 26d2308d-0464-45f9-be08-f03faed85ed5
Ancestors: VMMaker.oscog-nice.2550

Adopt the changes of VMMaker.oscog-eem.2552 except my own mistake of simplifying Float comparison

(because this makes NaN < x return true in JITTED code)

=============== Diff against VMMaker.oscog-nice.2550 ===============

Item was removed:
- ----- Method: CoInterpreter>>getPrimitiveDoMixedArithmetic (in category 'cog jit support') -----
- getPrimitiveDoMixedArithmetic
- <api>
- ^primitiveDoMixedArithmetic!

Item was changed:
  ----- Method: CogIA32Compiler>>generateCheckFeatures (in category 'feature detection') -----
  generateCheckFeatures
+ <inline: true>
  cogit
  PushR: EDX;
  PushR: ECX;
  PushR: EBX;
  MoveCq: 1 R: EAX;
  gen: CPUID;
  MoveR: EDX R: EAX;
  PopR: EBX;
  PopR: ECX;
  PopR: EDX;
  RetN: 0!

Item was changed:
  ----- Method: CogIA32Compiler>>generateCheckLZCNT (in category 'feature detection') -----
  generateCheckLZCNT
  "to check is Leading Zero Count operation is present
  cf. MSVC builtin __lzcnt documentation
  The result will be in bit 5 of return value (in EAX)"
+ <inline: true>
  cogit
  PushR: EDX;
  PushR: ECX;
  PushR: EBX;
  MoveCq: 16r80000001 R: EAX;
  gen: CPUID;
  MoveR: ECX R: EAX;
  PopR: EBX;
  PopR: ECX;
  PopR: EDX;
  RetN: 0!

Item was changed:
  ----- Method: CogIA32Compiler>>generateLowLevelTryLock: (in category 'multi-threading') -----
  generateLowLevelTryLock: vmOwnerLockAddress
  "Generate a function that attempts to lock the vmOwnerLock and answers
  true if it succeeded."
+ <inline: true>
  vmOwnerLockAddress = 0 ifTrue:
  [cogit
  MoveCq: 1 R: EAX;
  RetN: 0.
  ^self].
  cogit
  MoveCq: 1 R: EAX;
  gen: MFENCE; "make the XCHG globally consistent"
  gen: XCHGAwR operand: vmOwnerLockAddress operand: EAX;
  gen: SFENCE; "make the store globally visible"
  SubCq: 1 R: EAX; "Since we only ever set the lock to 1 or 0, subtracting 1 sets
    EAX to 0 if the lock was already locked and non-zero if it wasn't."
  RetN: 0!

Item was changed:
  ----- Method: CogMethodZone>>printCogMethods (in category 'printing') -----
  printCogMethods
  <api>
  <returnTypeC: #void>
+ self printCogMethodsSummarizing: false!
- | cogMethod nm nc no nf nu |
- <var: #cogMethod type: #'CogMethod *'>
- nm := nc := no := nf := nu := 0.
- cogMethod := coInterpreter cCoerceSimple: baseAddress to: #'CogMethod *'.
- [cogMethod < self limitZony] whileTrue:
- [coInterpreter printCogMethod: cogMethod.
- cogMethod cmType
- caseOf: {
- [CMFree] -> [nf := nf + 1].
- [CMMethod] -> [nm := nm + 1].
- [CMClosedPIC] -> [nc := nc + 1].
- [CMOpenPIC] -> [no:= no+ 1] }
- otherwise: [nu := nu + 1].
- cogMethod := self methodAfter: cogMethod].
- coInterpreter print: 'CMMethod '; printNum: nm;  print: ' CMClosedPIC '; printNum: nc;  print: ' CMOpenPIC '; printNum: no;  print: ' CMFree '; printNum: nf.
- nu > 0 ifTrue:
- [coInterpreter print: ' UNKNOWN '; printNum: nu].
- coInterpreter print: ' total '; printNum: nm+nc+no+nf+nu; cr!

Item was added:
+ ----- Method: CogMethodZone>>printCogMethodsSummarizing: (in category 'printing') -----
+ printCogMethodsSummarizing: summarize
+ <inline: true>
+ | cogMethod nm nc no nf nu |
+ <var: #cogMethod type: #'CogMethod *'>
+ nm := nc := no := nf := nu := 0.
+ cogMethod := coInterpreter cCoerceSimple: baseAddress to: #'CogMethod *'.
+ [cogMethod < self limitZony] whileTrue:
+ [summarize ifFalse:
+ [coInterpreter printCogMethod: cogMethod].
+ cogMethod cmType
+ caseOf: {
+ [CMFree] -> [nf := nf + 1].
+ [CMMethod] -> [nm := nm + 1].
+ [CMClosedPIC] -> [nc := nc + 1].
+ [CMOpenPIC] -> [no:= no+ 1] }
+ otherwise: [nu := nu + 1].
+ cogMethod := self methodAfter: cogMethod].
+ coInterpreter print: 'CMMethod '; printNum: nm;  print: ' CMClosedPIC '; printNum: nc;  print: ' CMOpenPIC '; printNum: no;  print: ' CMFree '; printNum: nf.
+ nu > 0 ifTrue:
+ [coInterpreter print: ' UNKNOWN '; printNum: nu].
+ coInterpreter print: ' total '; printNum: nm+nc+no+nf+nu; cr!

Item was changed:
  ----- Method: CogMethodZone>>printOpenPICList (in category 'accessing') -----
  printOpenPICList
  <api>
+ ^self printOpenPICListSummarizing: false!
- | n openPIC |
- <var: #openPIC type: #'CogMethod *'>
- n := 0.
- openPIC := openPICList.
- [openPIC == nil] whileFalse:
- [n := n + 1.
- coInterpreter printCogMethod: openPIC.
- openPIC := self cCoerceSimple: openPIC nextOpenPIC to: #'CogMethod *'].
- ^n!

Item was added:
+ ----- Method: CogMethodZone>>printOpenPICListSummarizing: (in category 'accessing') -----
+ printOpenPICListSummarizing: summarize
+ <inline: true>
+ | n openPIC |
+ <var: #openPIC type: #'CogMethod *'>
+ n := 0.
+ openPIC := openPICList.
+ [openPIC == nil] whileFalse:
+ [n := n + 1.
+ summarize ifFalse:
+ [coInterpreter printCogMethod: openPIC].
+ openPIC := self cCoerceSimple: openPIC nextOpenPIC to: #'CogMethod *'].
+ summarize ifTrue:
+ [coInterpreter print: 'num open PICs '; printNum: n; cr].
+ ^n!

Item was added:
+ ----- Method: CogMethodZone>>summarizeZone (in category 'printing') -----
+ summarizeZone
+ <doNotGenerate>
+ | pointer cogMethod ny nf nn |
+ <var: #cogMethod type: #'CogMethod *'>
+ self printCogMethodsSummarizing: true.
+ self printOpenPICListSummarizing: true.
+ ny := nf := nn := 0.
+ pointer := youngReferrers.
+ [pointer < limitAddress] whileTrue:
+ [cogMethod := coInterpreter cCoerceSimple: (objectMemory longAt: pointer) to: #'CogMethod *'.
+ cogMethod cmRefersToYoung ifTrue:
+ [ny := ny + 1].
+ cogMethod cmType = CMFree ifTrue:
+ [nf := nf + 1].
+ (cogMethod cmRefersToYoung or: [cogMethod cmType = CMFree]) ifFalse:
+ [nn := nn + 1].
+ pointer := pointer + objectMemory wordSize].
+ coInterpreter print: 'num free '; printNum: nf; print: ' num young '; printNum: ny; print: ' num neither '; printNum: nn; cr!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveEqual (in category 'primitive generators') -----
  genPrimitiveEqual
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpZero
  orDoubleComparison: #JumpFPEqual:
  invert: false]
  ifFalse: [self genSmallIntegerComparison: JumpZero]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatAdd (in category 'primitive generators') -----
  genPrimitiveFloatAdd
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleArithmetic: AddRdRd preOpCheck: nil]
  ifFalse: [self genPureDoubleArithmetic: AddRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatDivide (in category 'primitive generators') -----
  genPrimitiveFloatDivide
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]
  ifFalse: [self genPureDoubleArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatEqual (in category 'primitive generators') -----
  genPrimitiveFloatEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPEqual: invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatGreaterOrEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveFloatGreaterThan
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatLessOrEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: invert: true]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatLessThan (in category 'primitive generators') -----
  genPrimitiveFloatLessThan
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreater: invert: true]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatMultiply (in category 'primitive generators') -----
  genPrimitiveFloatMultiply
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleArithmetic: MulRdRd preOpCheck: nil]
  ifFalse: [self genPureDoubleArithmetic: MulRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveFloatNotEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPNotEqual: invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveFloatSubtract (in category 'primitive generators') -----
  genPrimitiveFloatSubtract
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleArithmetic: SubRdRd preOpCheck: nil]
  ifFalse: [self genPureDoubleArithmetic: SubRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveGreaterOrEqual
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpGreaterOrEqual
  orDoubleComparison: #JumpFPGreaterOrEqual:
  invert: false]
  ifFalse: [self genSmallIntegerComparison: JumpGreaterOrEqual]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveGreaterThan (in category 'primitive generators') -----
  genPrimitiveGreaterThan
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpGreater
  orDoubleComparison: #JumpFPGreater:
  invert: false]
  ifFalse: [self genSmallIntegerComparison: JumpGreater]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveLessOrEqual (in category 'primitive generators') -----
  genPrimitiveLessOrEqual
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpLessOrEqual
  orDoubleComparison: #JumpFPGreaterOrEqual:
  invert: true]
  ifFalse: [self genSmallIntegerComparison: JumpLessOrEqual]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveLessThan (in category 'primitive generators') -----
  genPrimitiveLessThan
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpLess
  orDoubleComparison: #JumpFPGreater:
  invert: true]
  ifFalse: [self genSmallIntegerComparison: JumpLess]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveNotEqual (in category 'primitive generators') -----
  genPrimitiveNotEqual
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self
  genSmallIntegerComparison: JumpNonZero
  orDoubleComparison: #JumpFPNotEqual:
  invert: false]
  ifFalse: [self genSmallIntegerComparison: JumpNonZero]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatAdd (in category 'primitive generators') -----
  genPrimitiveSmallFloatAdd
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatArithmetic: AddRdRd preOpCheck: nil]
  ifFalse: [self genPureSmallFloatArithmetic: AddRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatDivide (in category 'primitive generators') -----
  genPrimitiveSmallFloatDivide
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]
  ifFalse: [self genPureSmallFloatArithmetic: DivRdRd preOpCheck: #genDoubleFailIfZeroArgRcvr:arg:]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatEqual
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
  ifFalse: [self genPureSmallFloatComparison: #JumpFPEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatGreaterOrEqual
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]
  ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveSmallFloatGreaterThan
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]
  ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatLessOrEqual
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]
  ifFalse: [self genPureSmallFloatComparison: #JumpFPGreaterOrEqual: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatLessThan (in category 'primitive generators') -----
  genPrimitiveSmallFloatLessThan
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]
  ifFalse: [self genPureSmallFloatComparison: #JumpFPGreater: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatMultiply (in category 'primitive generators') -----
  genPrimitiveSmallFloatMultiply
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatArithmetic: MulRdRd preOpCheck: nil]
  ifFalse: [self genPureSmallFloatArithmetic: MulRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveSmallFloatNotEqual
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]
  ifFalse: [self genPureSmallFloatComparison: #JumpFPNotEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentation>>genPrimitiveSmallFloatSubtract (in category 'primitive generators') -----
  genPrimitiveSmallFloatSubtract
  <option: #Spur64BitMemoryManager>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genSmallFloatArithmetic: SubRdRd preOpCheck: nil]
  ifFalse: [self genPureSmallFloatArithmetic: SubRdRd preOpCheck: nil]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatEqual (in category 'primitive generators') -----
  genPrimitiveFloatEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPEqual: orIntegerComparison: JumpZero invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatGreaterOrEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpGreaterOrEqual invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatGreaterThan (in category 'primitive generators') -----
  genPrimitiveFloatGreaterThan
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpGreater invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: false]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessOrEqual (in category 'primitive generators') -----
  genPrimitiveFloatLessOrEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreaterOrEqual: orIntegerComparison: JumpLessOrEqual invert: true]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreaterOrEqual: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatLessThan (in category 'primitive generators') -----
  genPrimitiveFloatLessThan
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPGreater: orIntegerComparison: JumpLess invert: true]
  ifFalse: [self genPureDoubleComparison: #JumpFPGreater: invert: true]!

Item was changed:
  ----- Method: CogObjectRepresentationFor64BitSpur>>genPrimitiveFloatNotEqual (in category 'primitive generators') -----
  genPrimitiveFloatNotEqual
  <option: #DPFPReg0>
+ ^coInterpreter primitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic
  ifTrue: [self genDoubleComparison: #JumpFPNotEqual: orIntegerComparison: JumpNonZero invert: false]
  ifFalse: [self genPureDoubleComparison: #JumpFPNotEqual: invert: false]!

Item was changed:
  ----- Method: CogX64Compiler>>generateCheckLZCNT (in category 'feature detection') -----
  generateCheckLZCNT
  "to check is Leading Zero Count operation is present
  cf. MSVC builtin __lzcnt documentation
  The result will be in bit 5 of return value (in RAX)"
+ <inline: true>
  cogit
  PushR: RDX;
  PushR: RCX;
  PushR: RBX;
  MoveCq: 16r80000001 R: RAX;
  gen: CPUID;
  MoveR: RCX R: RAX;
  PopR: RBX;
  PopR: RCX;
  PopR: RDX;
  RetN: 0!

Item was changed:
  ----- Method: Cogit>>annotate:objRef: (in category 'method map') -----
  annotate: abstractInstruction objRef: anOop
  <var: #abstractInstruction type: #'AbstractInstruction *'>
  <returnTypeC: #'AbstractInstruction *'>
  (objectRepresentation shouldAnnotateObjectReference: anOop) ifTrue:
  [(objectMemory isYoungObject: anOop) ifTrue:
+ [self setHasYoungReferent: true].
- [hasYoungReferent := true].
  abstractInstruction annotation: IsObjectReference].
  ^abstractInstruction!

Item was changed:
  ----- Method: Cogit>>compileCogFullBlockMethod: (in category 'compile abstract instructions') -----
  compileCogFullBlockMethod: numCopied
  <returnTypeC: #'CogMethod *'>
  <option: #SistaV1BytecodeSet>
  | numBytecodes numBlocks numCleanBlocks result |
+ self setHasYoungReferent: (objectMemory isYoungObject: methodObj).
- hasYoungReferent := (objectMemory isYoungObject: methodObj).
  methodOrBlockNumArgs := coInterpreter argumentCountOf: methodObj.
  inBlock := InFullBlock.
  postCompileHook := nil.
  maxLitIndex := -1.
  self assert: (coInterpreter primitiveIndexOf: methodObj) = 0.
  initialPC := coInterpreter startPCOfMethod: methodObj.
  "initial estimate.  Actual endPC is determined in scanMethod."
  endPC := objectMemory numBytesOf: methodObj.
  numBytecodes := endPC - initialPC + 1.
  primitiveIndex := 0.
  self allocateOpcodes: (numBytecodes + 10) * self estimateOfAbstractOpcodesPerBytecodes
  bytecodes: numBytecodes
  ifFail: [^coInterpreter cCoerceSimple: MethodTooBig to: #'CogMethod *'].
  self flag: #TODO. "currently copiedValue access implies frameful method, this is suboptimal"
  (numBlocks := self scanMethod) < 0 ifTrue:
  [^coInterpreter cCoerceSimple: numBlocks to: #'CogMethod *'].
  self assert: numBlocks = 0. "blocks in full blocks are full blocks, they are not inlined."
  numCleanBlocks := self scanForCleanBlocks.
  self assert: numCleanBlocks = 0. "blocks in full blocks are full blocks, they are not inlined."
  self allocateBlockStarts: numBlocks + numCleanBlocks.
  blockCount := 0.
  numCleanBlocks > 0 ifTrue:
  [self addCleanBlockStarts].
  (self maybeAllocAndInitCounters
  and: [self maybeAllocAndInitIRCs]) ifFalse: "Inaccurate error code, but it'll do.  This will likely never fail."
  [^coInterpreter cCoerceSimple: InsufficientCodeSpace to: #'CogMethod *'].
 
  blockEntryLabel := nil.
  methodLabel dependent: nil.
  (result := self compileEntireFullBlockMethod: numCopied) < 0 ifTrue:
  [^coInterpreter cCoerceSimple: result to: #'CogMethod *'].
  ^self generateCogFullBlock!

Item was changed:
  ----- Method: Cogit>>compileCogMethod: (in category 'compile abstract instructions') -----
  compileCogMethod: selector
  <returnTypeC: #'CogMethod *'>
  | numBytecodes numBlocks numCleanBlocks result extra |
+ self setHasYoungReferent: ((objectMemory isYoungObject: methodObj)
+  or: [objectMemory isYoung: selector]).
- hasYoungReferent := (objectMemory isYoungObject: methodObj)
-  or: [objectMemory isYoung: selector].
  methodOrBlockNumArgs := coInterpreter argumentCountOf: methodObj.
  inBlock := 0.
  postCompileHook := nil.
  maxLitIndex := -1.
  extra := ((primitiveIndex := coInterpreter primitiveIndexOf: methodObj) > 0
  and: [(coInterpreter isQuickPrimitiveIndex: primitiveIndex) not])
  ifTrue: [30]
  ifFalse: [10].
  initialPC := coInterpreter startPCOfMethod: methodObj.
  "initial estimate.  Actual endPC is determined in scanMethod."
  endPC := (coInterpreter isQuickPrimitiveIndex: primitiveIndex)
  ifTrue: [initialPC - 1]
  ifFalse: [objectMemory numBytesOf: methodObj].
  numBytecodes := endPC - initialPC + 1.
  self allocateOpcodes: (numBytecodes + extra) * self estimateOfAbstractOpcodesPerBytecodes
  bytecodes: numBytecodes
  ifFail: [^coInterpreter cCoerceSimple: MethodTooBig to: #'CogMethod *'].
  (numBlocks := self scanMethod) < 0 ifTrue:
  [^coInterpreter cCoerceSimple: numBlocks to: #'CogMethod *'].
  numCleanBlocks := self scanForCleanBlocks.
  self methodFoundInvalidPostScan ifTrue:
  [^coInterpreter cCoerceSimple: ShouldNotJIT to: #'CogMethod *'].
  self allocateBlockStarts: numBlocks + numCleanBlocks.
  blockCount := 0.
  numCleanBlocks > 0 ifTrue:
  [self addCleanBlockStarts].
  (self maybeAllocAndInitCounters
  and: [self maybeAllocAndInitIRCs]) ifFalse: "Inaccurate error code, but it'll do.  This will likely never fail."
  [^coInterpreter cCoerceSimple: InsufficientCodeSpace to: #'CogMethod *'].
 
  blockEntryLabel := nil.
  methodLabel dependent: nil.
  (result := self compileEntireMethod) < 0 ifTrue:
  [^coInterpreter cCoerceSimple: result to: #'CogMethod *'].
  ^self generateCogMethod: selector!

Item was changed:
  ----- Method: Cogit>>genLoadInlineCacheWithSelector: (in category 'in-line cacheing') -----
  genLoadInlineCacheWithSelector: selectorIndex
  "The in-line cache for a send is implemented as a constant load into ClassReg.
  We always use a 32-bit load, even in 64-bits.
 
  In the initial (unlinked) state the in-line cache is notionally loaded with the selector.
  But since in 64-bits an arbitrary selector oop won't fit in a 32-bit constant load, we
  instead load the cache with the selector's index, either into the literal frame of the
  current method, or into the special selector array.  Negative values are 1-relative
  indices into the special selector array.
 
  When a send is linked, the load of the selector, or selector index, is overwritten with a
  load of the receiver's class, or class tag.  Hence, the 64-bit VM is currently constrained
  to use class indices as cache tags.  If out-of-line literals are used, distinct caches /must
  not/ share acche locations, for if they do, send cacheing will be confused by the sharing.
  Hence we use the MoveUniqueC32:R: instruction that will not share literal locations."
 
  | cacheValue |
  self assert: (selectorIndex < 0
  ifTrue: [selectorIndex negated between: 1 and: self numSpecialSelectors]
  ifFalse: [selectorIndex between: 0 and: (objectMemory literalCountOf: methodObj) - 1]).
 
  self inlineCacheTagsAreIndexes
  ifTrue:
  [cacheValue := selectorIndex]
  ifFalse:
  [| selector |
  selector := selectorIndex < 0
  ifTrue: [(coInterpreter specialSelector: -1 - selectorIndex)]
  ifFalse: [self getLiteral: selectorIndex].
  self assert: (objectMemory addressCouldBeOop: selector).
  (objectMemory isYoung: selector) ifTrue:
+ [self setHasYoungReferent: true].
- [hasYoungReferent := true].
  cacheValue := selector].
 
  self MoveUniqueC32: cacheValue R: ClassReg!

Item was changed:
  ----- Method: Cogit>>generateTrampolines (in category 'initialization') -----
  generateTrampolines
  "Generate the run-time entries and exits at the base of the native code zone and update the base.
  Read the class-side method trampolines for documentation on the various trampolines"
  | methodZoneStart |
  methodZoneStart := methodZoneBase.
  methodLabel address: methodZoneStart.
  self allocateOpcodes: 80 bytecodes: 0.
+ self setHasYoungReferent: false.
- hasYoungReferent := false.
  objectRepresentation maybeGenerateSelectorIndexDereferenceRoutine.
  self generateSendTrampolines.
  self generateMissAbortTrampolines.
  objectRepresentation generateObjectRepresentationTrampolines.
  self generateRunTimeTrampolines.
  NewspeakVM ifTrue: [self generateNewspeakRuntime].
  SistaVM ifTrue: [self generateSistaRuntime].
  self generateEnilopmarts.
  self generateTracingTrampolines.
 
  "finish up"
  self recordGeneratedRunTime: 'methodZoneBase' address: methodZoneBase.
  processor flushICacheFrom: methodZoneStart asUnsignedInteger to: methodZoneBase asUnsignedInteger!

Item was changed:
  ----- Method: Cogit>>maybeGenerateCheckLZCNT (in category 'initialization') -----
  maybeGenerateCheckLZCNT
  | startAddress |
  <inline: true>
  backEnd numCheckLZCNTOpcodes > 0 ifTrue:
  [self allocateOpcodes: backEnd numCheckLZCNTOpcodes bytecodes: 0.
  startAddress := methodZoneBase.
+ methodLabel address: startAddress. "for pc-relative MoveCq: 16r80000001 R: RAX;"
  backEnd generateCheckLZCNT.
  self outputInstructionsForGeneratedRuntimeAt: startAddress.
  self recordGeneratedRunTime: 'ceCheckLZCNTFunction' address: startAddress.
  ceCheckLZCNTFunction := self cCoerceSimple: startAddress to: #'usqIntptr_t (*)(void)']!

Item was added:
+ ----- Method: Cogit>>setHasYoungReferent: (in category 'accessing') -----
+ setHasYoungReferent: boolean
+ "Written this way to allow reak-pointing in the simulator."
+ <cmacro: '(b) (hasYoungReferent = (b))'>
+ boolean ifTrue:
+ [self halt].
+ "(hasYoungReferent == false and: [boolean == true]) ifTrue:
+ [self halt]."
+ hasYoungReferent := boolean!

Item was removed:
- ----- Method: CurrentImageCoInterpreterFacade>>getPrimitiveDoMixedArithmetic (in category 'cog jit support') -----
- getPrimitiveDoMixedArithmetic
- ^coInterpreter getPrimitiveDoMixedArithmetic ifNil: [true]!

Item was added:
+ ----- Method: CurrentImageCoInterpreterFacade>>primitiveDoMixedArithmetic (in category 'cog jit support') -----
+ primitiveDoMixedArithmetic
+ ^coInterpreter primitiveDoMixedArithmetic ifNil: [true]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveHighBit (in category 'arithmetic integer primitives') -----
  primitiveHighBit
  | integerReceiverOop leadingZeroCount highestBitZeroBased |
  integerReceiverOop := self stackTop.
  "Convert the receiver Oop to use a single tag bit"
  self numSmallIntegerTagBits > 1
  ifTrue: [integerReceiverOop := (integerReceiverOop >>> (self numSmallIntegerTagBits-1) bitOr: 1)].
  self cppIf: #'__GNUC__' defined
  ifTrue:
  ["Note: in gcc, result is undefined if input is zero (for compatibility with BSR fallback when no CLZ instruction available).
  but input is never zero because we pass the oop with tag bits set, so we are safe"
  objectMemory wordSize = 4
  ifTrue: [leadingZeroCount := self __builtin_clz: integerReceiverOop]
  ifFalse: [leadingZeroCount := self __builtin_clzll: integerReceiverOop].
  leadingZeroCount = 0
  ifTrue:
  ["highBit is not defined for negative Integer"
  self primitiveFail]
  ifFalse:
  ["Nice bit trick: 1-based high-bit is (32 - clz) - 1 to account for tag bit.
  This is like two-complement - clz - 1 on 5 bits, or in other words a bit-invert operation clz ^16r1F"
  self pop: 1 thenPushInteger: (leadingZeroCount bitXor: (BytesPerWord * 8 - 1))].
  ^self].
  self cppIf: #'__GNUC__' defined not & (#'_MSC_VER' defined | #'__ICC' defined)
  ifTrue:
  ["In MSVC, _lzcnt and _lzcnt64 builtins do not fallback to BSR when not supported by CPU
  Instead of messing with __cpuid() we always use the BSR intrinsic"
 
  "Trick: we test the oop sign rather than the integerValue. Assume oop are signed (so far, they are, sqInt are signed)"
  integerReceiverOop < 0 ifTrue: [self primitiveFail] ifFalse: [
  "Setting this variable is useless, but VMMaker will generate it at a worse place"
  highestBitZeroBased := 0.
  "We do not even test the return value, because integerReceiverOop is never zero"
  self cCode: [objectMemory wordSize = 4
  ifTrue: [self _BitScanReverse: highestBitZeroBased address _: integerReceiverOop]
  ifFalse: [self _BitScanReverse64: highestBitZeroBased address _: integerReceiverOop]]
  inSmalltalk: [highestBitZeroBased := integerReceiverOop highBit - 1].
  "thanks to the tag bit, the +1 operation for getting 1-based rank is not necessary"
  self pop: 1 thenPushInteger: highestBitZeroBased].
  ^self].
  self cppIf:  #'__GNUC__' defined not & #'_MSC_VER' defined not & #'__ICC' defined not
  ifTrue:
  ["not gcc/clang, nor MSVC/ICC, you have to implement if your compiler provide useful builtins"
+ self cCode:
+ [self primitiveFail]
+ inSmalltalk: "Simulate so that the simulatror is closer to the actual VM"
+ [integerReceiverOop < 0
+ ifTrue: [self primitiveFail]
+ ifFalse: [self pop: 1 thenPushInteger: integerReceiverOop highBit - 1]]]!
- self primitiveFail].!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatEqual
  <option: #Spur64BitMemoryManager>
+ | rcvr arg |
- | rcvr arg intArg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  arg := objectMemory loadFloatOrIntFrom: self stackTop.
  self successful ifTrue:
+ [(rcvr = arg
+  and: [objectMemory isIntegerObject: self stackTop])
+ ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [| intArg |
+ intArg := objectMemory integerValueOf: self stackTop.
+ self pop: 2 thenPushBool: rcvr asInteger = intArg]
- [self cppIf: objectMemory wordSize > 4
- ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- intArg := objectMemory integerValueOf: self stackTop.
- self pop: 2 thenPushBool: rcvr asInteger = intArg]
- ifFalse: [self pop: 2 thenPushBool: rcvr = arg]]
  ifFalse: [self pop: 2 thenPushBool: rcvr = arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatGreaterOrEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatGreaterOrEqual
  <option: #Spur64BitMemoryManager>
+ | rcvr arg |
- | rcvr arg intArg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  arg := objectMemory loadFloatOrIntFrom: self stackTop.
  self successful ifTrue:
+ [(rcvr = arg
+  and: [objectMemory isIntegerObject: self stackTop])
+ ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [| intArg |
+ intArg := objectMemory integerValueOf: self stackTop.
+ self pop: 2 thenPushBool: rcvr asInteger >= intArg]
- [self cppIf: objectMemory wordSize > 4
- ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- intArg := objectMemory integerValueOf: self stackTop.
- self pop: 2 thenPushBool: rcvr asInteger >= intArg]
- ifFalse: [self pop: 2 thenPushBool: rcvr >= arg]]
  ifFalse: [self pop: 2 thenPushBool: rcvr >= arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatGreaterThan (in category 'arithmetic float primitives') -----
  primitiveSmallFloatGreaterThan
  <option: #Spur64BitMemoryManager>
+ | rcvr arg |
- | rcvr arg intArg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  arg := objectMemory loadFloatOrIntFrom: self stackTop.
  self successful ifTrue:
+ [(rcvr = arg
+  and: [objectMemory isIntegerObject: self stackTop])
+ ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [| intArg |
+ intArg := objectMemory integerValueOf: self stackTop.
+ self pop: 2 thenPushBool: rcvr asInteger > intArg]
- [self cppIf: objectMemory wordSize > 4
- ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- intArg := objectMemory integerValueOf: self stackTop.
- self pop: 2 thenPushBool: rcvr asInteger > intArg]
- ifFalse: [self pop: 2 thenPushBool: rcvr > arg]]
  ifFalse: [self pop: 2 thenPushBool: rcvr > arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatLessOrEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatLessOrEqual
  <option: #Spur64BitMemoryManager>
+ | rcvr arg |
- | rcvr arg intArg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  arg := objectMemory loadFloatOrIntFrom: self stackTop.
  self successful ifTrue:
+ [(rcvr = arg
+  and: [objectMemory isIntegerObject: self stackTop])
+ ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [| intArg |
+ intArg := objectMemory integerValueOf: self stackTop.
+ self pop: 2 thenPushBool: rcvr asInteger <= intArg]
- [self cppIf: objectMemory wordSize > 4
- ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- intArg := objectMemory integerValueOf: self stackTop.
- self pop: 2 thenPushBool: rcvr asInteger <= intArg]
- ifFalse: [self pop: 2 thenPushBool: rcvr <= arg]]
  ifFalse: [self pop: 2 thenPushBool: rcvr <= arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatLessThan (in category 'arithmetic float primitives') -----
  primitiveSmallFloatLessThan
  <option: #Spur64BitMemoryManager>
+ | rcvr arg |
- | rcvr arg intArg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  arg := objectMemory loadFloatOrIntFrom: self stackTop.
  self successful ifTrue:
+ [(rcvr = arg
+  and: [objectMemory isIntegerObject: self stackTop])
+ ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [| intArg |
+ intArg := objectMemory integerValueOf: self stackTop.
+ self pop: 2 thenPushBool: rcvr asInteger < intArg]
- [self cppIf: objectMemory wordSize > 4
- ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- intArg := objectMemory integerValueOf: self stackTop.
- self pop: 2 thenPushBool: rcvr asInteger < intArg]
- ifFalse: [self pop: 2 thenPushBool: rcvr < arg]]
  ifFalse: [self pop: 2 thenPushBool: rcvr < arg]]!

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveSmallFloatNotEqual (in category 'arithmetic float primitives') -----
  primitiveSmallFloatNotEqual
  <option: #Spur64BitMemoryManager>
+ | rcvr arg |
- | rcvr arg intArg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory smallFloatValueOf: (self stackValue: 1).
  arg := objectMemory loadFloatOrIntFrom: self stackTop.
  self successful ifTrue:
+ [(rcvr = arg
+  and: [objectMemory isIntegerObject: self stackTop])
+ ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [| intArg |
+ intArg := objectMemory integerValueOf: self stackTop.
+ self pop: 2 thenPushBool: (rcvr asInteger = intArg) not]
- [self cppIf: objectMemory wordSize > 4
- ifTrue: [((objectMemory isIntegerObject: self stackTop) and: [rcvr = arg])
- ifTrue: ["Resolve case of ambiguity so as to have comparison of exact values"
- intArg := objectMemory integerValueOf: self stackTop.
- self pop: 2 thenPushBool: (rcvr asInteger = intArg) not]
- ifFalse: [self pop: 2 thenPushBool: (rcvr = arg) not]]
  ifFalse: [self pop: 2 thenPushBool: (rcvr = arg) not]]!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genNSSend:numArgs:depth:sendTable: (in category 'bytecode generators') -----
  genNSSend: selectorIndex numArgs: numArgs depth: depth sendTable: sendTable
  <var: #sendTable type: #'sqInt *'>
  | selector nsSendCache |
  self assert: (selectorIndex between: 0 and: (objectMemory literalCountOf: methodObj) - 1).
  selector := self getLiteral: selectorIndex.
  self assert: (objectMemory addressCouldBeOop: selector).
  (objectMemory isYoung: selector) ifTrue:
+ [self setHasYoungReferent: true].
- [hasYoungReferent := true].
 
  nsSendCache := theIRCs + (NumOopsPerNSC * objectMemory bytesPerOop * indexOfIRC).
  indexOfIRC := indexOfIRC + 1.
  self assert: (objectMemory isInOldSpace: nsSendCache).
  self initializeNSSendCache: nsSendCache selector: selector numArgs: numArgs depth: depth.
 
  "This leaves the method receiver on the stack, which might not be the implicit receiver.
  But the lookup trampoline will establish the on-stack receiver once it locates it."
  self marshallAbsentReceiverSendArguments: numArgs.
 
  "Load the cache last so it is a fixed distance from the call."
  self MoveUniqueCw: nsSendCache R: SendNumArgsReg.
  self CallNewspeakSend: (sendTable at: (numArgs min: NumSendTrampolines - 1)).
 
  self PushR: ReceiverResultReg.
  ^0!

Item was changed:
  ----- Method: Spur32BitMemoryManager>>loadFloatOrIntFrom: (in category 'interpreter access') -----
  loadFloatOrIntFrom: floatOrInt
  "If floatOrInt is an integer and we enable mixed arithmetic in primitives, then convert it to a C double float and return it.
  If it is a Float, then load its value and return it.
  Otherwise fail -- ie return with primErrorCode non-zero."
 
  <inline: true>
  <returnTypeC: #double>
 
+ (coInterpreter primitiveDoMixedArithmetic and: [self isIntegerObject: floatOrInt]) ifTrue:
- (self primitiveDoMixedArithmetic and: [self isIntegerObject: floatOrInt]) ifTrue:
  [^(self integerValueOf: floatOrInt) asFloat].
  ^self floatValueOf: floatOrInt!

Item was changed:
  ----- Method: StackInterpreter>>primitiveDoMixedArithmetic (in category 'primitive support') -----
  primitiveDoMixedArithmetic
  "If primitiveDoMixedArithmetic is true, then primitive can handle the conversions:
  SmallInteger arithmeticOp: Float (Small or Boxed)
  SmallInteger compareOp: Float (Small or Boxed)
  Else, the primitive fail in case of mixed arithmetic, and conversion should be performed at image side"
+ <api>
+ <cmacro: '() GIV(primitiveDoMixedArithmetic)'>
- <cmacro: '() primitiveDoMixedArithmetic'>
  ^primitiveDoMixedArithmetic!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatEqual:toArg: (in category 'comparison float primitives') -----
  primitiveFloatEqual: rcvrOop toArg: argOop
  | rcvr arg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  arg := objectMemory loadFloatOrIntFrom: argOop.
+ (objectMemory wordSize > 4
+ and: [rcvr = arg]) ifTrue:
+ [(objectMemory isIntegerObject: argOop) ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [^rcvr asInteger = (objectMemory integerValueOf: argOop)].
+ (objectMemory isIntegerObject: rcvrOop) ifTrue:
+ ["Same when used from bytecodePrim...
+  note that rcvr and arg cannot be both integer (case is already handled)"
+ ^(objectMemory integerValueOf: rcvrOop) = arg asInteger]].
- self cppIf: objectMemory wordSize > 4
- ifTrue: [rcvr = arg
- ifTrue:
- [(objectMemory isIntegerObject: argOop)
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- ^ rcvr asInteger = (objectMemory integerValueOf: argOop)]
- ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- ifTrue:
- ["Same when used from bytecodePrim...
- note that rcvr and arg cannot be both integer (case is already handled)"
- ^ (objectMemory integerValueOf: rcvrOop) = arg asInteger]]]].
  ^rcvr = arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatGreater:thanArg: (in category 'comparison float primitives') -----
  primitiveFloatGreater: rcvrOop thanArg: argOop
  | rcvr arg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  arg := objectMemory loadFloatOrIntFrom: argOop.
+ (objectMemory wordSize > 4
+ and: [rcvr = arg]) ifTrue:
+ [(objectMemory isIntegerObject: argOop) ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [^rcvr asInteger > (objectMemory integerValueOf: argOop)].
+ (objectMemory isIntegerObject: rcvrOop) ifTrue:
+ ["Same when used from bytecodePrim...
+  note that rcvr and arg cannot be both integer (case is already handled)"
+ ^(objectMemory integerValueOf: rcvrOop) > arg asInteger]].
- self cppIf: objectMemory wordSize > 4
- ifTrue: [rcvr = arg
- ifTrue:
- [(objectMemory isIntegerObject: argOop)
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- ^ rcvr asInteger > (objectMemory integerValueOf: argOop)]
- ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- ifTrue:
- ["Same when used from bytecodePrim...
- note that rcvr and arg cannot be both integer (case is already handled)"
- ^ (objectMemory integerValueOf: rcvrOop) > arg asInteger]]]].
  ^rcvr > arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatGreaterOrEqual:toArg: (in category 'comparison float primitives') -----
  primitiveFloatGreaterOrEqual: rcvrOop toArg: argOop
  | rcvr arg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  arg := objectMemory loadFloatOrIntFrom: argOop.
+ (objectMemory wordSize > 4
+ and: [rcvr = arg]) ifTrue:
+ [(objectMemory isIntegerObject: argOop) ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [^rcvr asInteger >= (objectMemory integerValueOf: argOop)].
+ (objectMemory isIntegerObject: rcvrOop) ifTrue:
+ ["Same when used from bytecodePrim...
+  note that rcvr and arg cannot be both integer (case is already handled)"
+ ^(objectMemory integerValueOf: rcvrOop) >= arg asInteger]].
- self cppIf: objectMemory wordSize > 4
- ifTrue: [rcvr = arg
- ifTrue:
- [(objectMemory isIntegerObject: argOop)
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- ^ rcvr asInteger >= (objectMemory integerValueOf: argOop)]
- ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- ifTrue:
- ["Same when used from bytecodePrim...
- note that rcvr and arg cannot be both integer (case is already handled)"
- ^ (objectMemory integerValueOf: rcvrOop) >= arg asInteger]]]].
  ^rcvr >= arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatLess:thanArg: (in category 'comparison float primitives') -----
  primitiveFloatLess: rcvrOop thanArg: argOop
  | rcvr arg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  arg := objectMemory loadFloatOrIntFrom: argOop.
+ (objectMemory wordSize > 4
+ and: [rcvr = arg]) ifTrue:
+ [(objectMemory isIntegerObject: argOop) ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [^rcvr asInteger < (objectMemory integerValueOf: argOop)].
+ (objectMemory isIntegerObject: rcvrOop) ifTrue:
+ ["Same when used from bytecodePrim...
+  note that rcvr and arg cannot be both integer (case is already handled)"
+ ^(objectMemory integerValueOf: rcvrOop) < arg asInteger]].
- self cppIf: objectMemory wordSize > 4
- ifTrue: [rcvr = arg
- ifTrue:
- [(objectMemory isIntegerObject: argOop)
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- ^ rcvr asInteger < (objectMemory integerValueOf: argOop)]
- ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- ifTrue:
- ["Same when used from bytecodePrim...
- note that rcvr and arg cannot be both integer (case is already handled)"
- ^ (objectMemory integerValueOf: rcvrOop) < arg asInteger]]]].
  ^rcvr < arg!

Item was changed:
  ----- Method: StackInterpreter>>primitiveFloatLessOrEqual:toArg: (in category 'comparison float primitives') -----
  primitiveFloatLessOrEqual: rcvrOop toArg: argOop
  | rcvr arg |
  <var: #rcvr type: #double>
  <var: #arg type: #double>
 
  rcvr := objectMemory loadFloatOrIntFrom: rcvrOop.
  arg := objectMemory loadFloatOrIntFrom: argOop.
+ (objectMemory wordSize > 4
+ and: [rcvr = arg]) ifTrue:
+ [(objectMemory isIntegerObject: argOop) ifTrue: "Resolve case of ambiguity so as to have comparison of exact values"
+ [^rcvr asInteger <= (objectMemory integerValueOf: argOop)].
+ (objectMemory isIntegerObject: rcvrOop) ifTrue:
+ ["Same when used from bytecodePrim...
+  note that rcvr and arg cannot be both integer (case is already handled)"
+ ^(objectMemory integerValueOf: rcvrOop) <= arg asInteger]].
- self cppIf: objectMemory wordSize > 4
- ifTrue: [rcvr = arg
- ifTrue:
- [(objectMemory isIntegerObject: argOop)
- ifTrue:
- ["Resolve case of ambiguity so as to have comparison of exact values"
- ^ rcvr asInteger <= (objectMemory integerValueOf: argOop)]
- ifFalse: [(objectMemory isIntegerObject: rcvrOop)
- ifTrue:
- ["Same when used from bytecodePrim...
- note that rcvr and arg cannot be both integer (case is already handled)"
- ^ (objectMemory integerValueOf: rcvrOop) <= arg asInteger]]]].
  ^rcvr <= arg!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genNSSend:numArgs:depth:sendTable: (in category 'bytecode generators') -----
  genNSSend: selectorIndex numArgs: numArgs depth: depth sendTable: sendTable
  <var: #sendTable type: #'sqInt *'>
  | selector nsSendCache |
  self assert: (selectorIndex between: 0 and: (objectMemory literalCountOf: methodObj) - 1).
  selector := self getLiteral: selectorIndex.
  self assert: (objectMemory addressCouldBeOop: selector).
  (objectMemory isYoung: selector) ifTrue:
+ [self setHasYoungReferent: true].
- [hasYoungReferent := true].
 
  nsSendCache := theIRCs + (NumOopsPerNSC * objectMemory bytesPerOop * indexOfIRC).
  indexOfIRC := indexOfIRC + 1.
  self assert: (objectMemory isInOldSpace: nsSendCache).
  self initializeNSSendCache: nsSendCache selector: selector numArgs: numArgs depth: depth.
 
  self ssAllocateCallReg: SendNumArgsReg.
 
  "This may leave the method receiver on the stack, which might not be the implicit receiver.
  But the lookup trampoline will establish an on-stack receiver once it locates it."
  self marshallAbsentReceiverSendArguments: numArgs.
 
  "Load the cache last so it is a fixed distance from the call."
  self MoveUniqueCw: nsSendCache R: SendNumArgsReg.
  self CallNewspeakSend: (sendTable at: (numArgs min: NumSendTrampolines - 1)).
 
  self voidReceiverOptStatus.
  self ssPushRegister: ReceiverResultReg.
  ^0!