[Vm-dev] VM Maker: VMMaker.oscog-eem.2742.mcz
Eliot Miranda
eliot.miranda at gmail.com
Wed Apr 22 20:37:00 UTC 2020
Hi Nicolas,
On Wed, Apr 22, 2020 at 12:27 PM Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com> wrote:
>
> Hi Eliot,
> I don't know if I can help you wrt to Mac library system which is a bit
> opaque to me (I never took time to inquire this framework thing).
> But I can try setting tests to verify which version is used.
> On 64 bits macos, I still have this libm bug:
> https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/383
> So we have at least one easy test case telling us if we effectively link
> against fdlibm or not: the regular Squeak FloatTest fails if we link ldexp
> against apple's libm.
>
OK, good, that's a useful test. So far I have your fork of fdlibm
compiling and linking against the VM on 64-bit Mac, and am working on
64-bit Windows (cygwin). Once I have that working I'll commit and you can
review. I'll commit on Cog because it doesn't affect normal builds, being
dead code to any build that doesn't set BIT_IDENTICAL_FLOATING_POINT in the
Makefile (you'll see what I mean when you view the commit).
> Otherwisen we can compile the FloatMathPlugin and compare results of
> regular primitives vs FloatMathPlugin primitives on some well chosen
> cases... (or a big list of random cases...).
> We can contact on Discord tomorrow around 19h00 UTC if you want.
>
Yes, please. I want to discuss this with you to see if I have the right
idea/misunderastand something fundamental, am doing the right thing/wasting
effort, etc. Hopefully there will be code for is to look at in Cog by then.
Cheers!
> Le mer. 22 avr. 2020 à 02:45, Eliot Miranda <eliot.miranda at gmail.com> a
> écrit :
>
>>
>> Hi Nicoilas,
>>
>> On Tue, Apr 21, 2020 at 6:16 AM Nicolas Cellier <
>> nicolas.cellier.aka.nice at gmail.com> wrote:
>>
>>>
>>> Hi Eliot,
>>> IEEE754 mandates that sqrt be correctly rounded.
>>> Hence it should be bit identical on every compliant architecture.
>>>
>>
>> That's good to know.! I c an change thin gas back soon. First I want to
>> see that I can link the VM against
>> https://github.com/nicolas-cellier-aka-nice/fdlibm.git. I have modified
>> the Mac makefile to build libm.a from your fdlibm, and link against it but
>> so far I'm not sure if the m is actually using the code. Would you have
>> time for us to discuss in a video chat, say on Discord, some times this
>> week? I'm simply not confident with the math side of things. You're the
>> expert and I need your input.
>>
>> + aClass interpreterClass.
>>>> + aClass objectMemoryClass} do:
>>>> + [:scopeOrNil|
>>>> + scopeOrNil ifNotNil:
>>>> + [:scope|
>>>> + (scope bindingOf: key) ifNotNil:
>>>> + [:binding|
>>>> + binding value ~~ true ifTrue:
>>>> [^true]]]].
>>>> + ^false!
>>>>
>>>> Item was changed:
>>>> ----- Method: CCodeGenerator>>shouldIncludeMethodFor:selector: (in
>>>> category 'utilities') -----
>>>> shouldIncludeMethodFor: aClass selector: selector
>>>> "Answer whether a method shoud be translated. Process optional
>>>> methods by
>>>> interpreting the argument to the option: pragma as either a
>>>> Cogit class name
>>>> or a class variable name or a variable name in
>>>> VMBasicConstants. Exclude
>>>> methods with the doNotGenerate pragma."
>>>> | optionPragmas notOptionPragmas |
>>>> (aClass >> selector pragmaAt: #doNotGenerate) ifNotNil:
>>>> [^false].
>>>>
>>>> "where is pragmasAt: ??"
>>>> optionPragmas := (aClass >> selector) pragmas select: [:p| p
>>>> keyword == #option:].
>>>> notOptionPragmas := (aClass >> selector) pragmas select: [:p| p
>>>> keyword == #notOption:].
>>>> (optionPragmas notEmpty or: [notOptionPragmas notEmpty]) ifTrue:
>>>> + ["We have to include the method if either
>>>> + - any one of the options is false (because we
>>>> want #if option...)
>>>> + - any one of the notOptions is true (because we
>>>> want #if !!option...)
>>>> + - all of the options is true and all of the
>>>> notOptions are false (because they have all been satisfied)"
>>>> + ^((optionPragmas anySatisfy: [:pragma| (self
>>>> optionIsTrue: pragma in: aClass) not])
>>>> + and: [notOptionPragmas anySatisfy: [:pragma| (self
>>>> optionIsFalse: pragma in: aClass) not]])
>>>> + or: [(optionPragmas allSatisfy: [:pragma| self
>>>> optionIsTrue: pragma in: aClass])
>>>> + and: [notOptionPragmas allSatisfy: [:pragma|
>>>> self optionIsFalse: pragma in: aClass]]]].
>>>> - [^(optionPragmas allSatisfy: [:pragma| self
>>>> optionIsTrue: pragma in: aClass])
>>>> - and: [notOptionPragmas noneSatisfy: [:pragma| self
>>>> optionIsTrue: pragma in: aClass]]].
>>>>
>>>> ^true!
>>>>
>>>> Item was changed:
>>>> ----- Method: CCodeGenerator>>variableDeclarationStringsForVariable:
>>>> (in category 'C translation support') -----
>>>> variableDeclarationStringsForVariable: variableNameString
>>>> "We (have to?) abuse declarations for optionality using #if C
>>>> preprocessor forms.
>>>> This is ugly, but difficult to avoid. This routine answers
>>>> either a single string declaration
>>>> for a variable declared without one of these hacks, or returns
>>>> the declaration split up into lines."
>>>> | declString |
>>>> declString := variableDeclarations at: variableNameString
>>>> ifAbsent: [^{'sqInt ', variableNameString}].
>>>> + ^((declString includes: $#) and: [declString includes: $\])
>>>> - ^(declString includes: $#)
>>>> ifTrue: [declString withCRs findTokens: Character cr]
>>>> ifFalse: [{declString}]!
>>>>
>>>> Item was changed:
>>>> ----- Method: CogObjectRepresentation>>genPrimitiveFloatSquareRoot
>>>> (in category 'primitive generators') -----
>>>> genPrimitiveFloatSquareRoot
>>>> + <notOption: #BIT_IDENTICAL_FLOATING_POINT>
>>>> <option: #DPFPReg0>
>>>> | jumpFailAlloc |
>>>> <var: #jumpFailAlloc type: #'AbstractInstruction *'>
>>>> cogit processorHasDoublePrecisionFloatingPointSupport ifFalse:
>>>> [^UnimplementedPrimitive].
>>>> self genGetDoubleValueOf: ReceiverResultReg into: DPFPReg0.
>>>> cogit SqrtRd: DPFPReg0.
>>>> jumpFailAlloc := self
>>>> genAllocFloatValue:
>>>> DPFPReg0
>>>> into: SendNumArgsReg
>>>> scratchReg: ClassReg
>>>> scratchReg: TempReg.
>>>> cogit MoveR: SendNumArgsReg R: ReceiverResultReg.
>>>> cogit genPrimReturn.
>>>> jumpFailAlloc jmpTarget: cogit Label.
>>>> ^0!
>>>>
>>>> Item was changed:
>>>> ----- Method:
>>>> CogObjectRepresentation>>genPrimitiveSmallFloatSquareRoot (in category
>>>> 'primitive generators') -----
>>>> genPrimitiveSmallFloatSquareRoot
>>>> + <notOption: #BIT_IDENTICAL_FLOATING_POINT>
>>>> <option: #Spur64BitMemoryManager>
>>>> + <option: #DPFPReg0>
>>>> | jumpFailAlloc jumpNegative |
>>>> <var: #jumpFailAlloc type: #'AbstractInstruction *'>
>>>> <var: #jumpNegative type: #'AbstractInstruction *'>
>>>> self genGetSmallFloatValueOf: ReceiverResultReg scratch:
>>>> SendNumArgsReg into: DPFPReg0.
>>>> cogit
>>>> XorRd: DPFPReg1 Rd: DPFPReg1; "+0.0 is all zeros"
>>>> CmpRd: DPFPReg0 Rd: DPFPReg1.
>>>> jumpNegative := cogit JumpFPGreater: 0.
>>>> cogit SqrtRd: DPFPReg0.
>>>> jumpFailAlloc := self
>>>> genAllocFloatValue:
>>>> DPFPReg0
>>>> into: SendNumArgsReg
>>>> scratchReg: ClassReg
>>>> scratchReg: TempReg.
>>>> cogit MoveR: SendNumArgsReg R: ReceiverResultReg.
>>>> cogit genPrimReturn.
>>>> jumpNegative jmpTarget: (jumpFailAlloc jmpTarget: cogit Label).
>>>> ^0!
>>>>
>>>> Item was changed:
>>>> ----- Method: CogPrimitiveDescriptor>>printCInitializerOn:in: (in
>>>> category 'translation') -----
>>>> printCInitializerOn: aStream in: aCCodeGenerator
>>>> <doNotGenerate>
>>>> + | first hasCompileTimeOptionPragmas |
>>>> + hasCompileTimeOptionPragmas := false.
>>>> + primitiveGenerator ifNotNil:
>>>> + [:sel|
>>>> + (aCCodeGenerator methodNamed: sel) ifNotNil:
>>>> + [:method|
>>>> + method compileTimeOptionPragmas ifNotEmpty:
>>>> + [:ctop|
>>>> + aStream position: aStream position - 1.
>>>> + method outputConditionalDefineFor:
>>>> ctop on: aStream.
>>>> + aStream tab.
>>>> + hasCompileTimeOptionPragmas := true]]].
>>>> +
>>>> - | first |
>>>> - first := true.
>>>> aStream nextPut: ${; space.
>>>> + first := true.
>>>> self class instVarNamesAndTypesForTranslationDo:
>>>> [:ivn :type| | value |
>>>> first ifTrue: [first := false] ifFalse: [aStream
>>>> nextPut: $,; space].
>>>> value := self instVarNamed: ivn.
>>>> aStream nextPutAll: (value
>>>>
>>>> ifNotNil: [value isSymbol
>>>>
>>>> ifTrue: [aCCodeGenerator cFunctionNameFor: value]
>>>>
>>>> ifFalse: [aCCodeGenerator cLiteralFor: value]]
>>>> ifNil:
>>>> ['0'])].
>>>> + aStream space; nextPut: $}.
>>>> + hasCompileTimeOptionPragmas ifTrue:
>>>> + [aStream nextPut: $,; cr; nextPutAll: '#else'; crtab.
>>>> + self copy primitiveGenerator: nil; primNumArgs: -1;
>>>> printCInitializerOn: aStream in: aCCodeGenerator.
>>>> + aStream nextPut: $,; cr; nextPutAll: '#endif']!
>>>> - aStream space; nextPut: $}!
>>>>
>>>> Item was changed:
>>>> ----- Method: Cogit class>>tableInitializerFor:in: (in category
>>>> 'translation') -----
>>>> tableInitializerFor: aTable in: aCCodeGenerator
>>>> ^String streamContents:
>>>> [:s|
>>>> s nextPutAll: ' = {'.
>>>> aTable object
>>>> do: [:gt|
>>>> s crtab.
>>>> gt printCInitializerOn: s in:
>>>> aCCodeGenerator]
>>>> + separatedBy: [s peekLast == $} ifTrue: [s
>>>> nextPut: $,]].
>>>> - separatedBy: [s nextPut: $,].
>>>> s cr; nextPut: $}]!
>>>>
>>>> Item was changed:
>>>> ----- Method: Interpreter class>>initializePrimitiveTable (in
>>>> category 'initialization') -----
>>>> (excessive size, no diff calculated)
>>>>
>>>> Item was removed:
>>>> - ----- Method:
>>>> InterpreterPrimitives>>primitiveArrayBecomeOneWayCopyHash (in category
>>>> 'object access primitives') -----
>>>> - primitiveArrayBecomeOneWayCopyHash
>>>> - "Similar to primitiveArrayBecomeOneWay but accepts a third
>>>> argument deciding whether to
>>>> - copy the receiver's elements identity hashes over the
>>>> argument's elements identity hashes."
>>>> -
>>>> - | copyHashFlag ec |
>>>> - self stackTop = objectMemory trueObject
>>>> - ifTrue: [copyHashFlag := true]
>>>> - ifFalse:
>>>> - [self stackTop = objectMemory falseObject
>>>> - ifTrue: [copyHashFlag := false]
>>>> - ifFalse:
>>>> - [self primitiveFailFor:
>>>> PrimErrBadArgument.
>>>> - ^nil]].
>>>> - ec := objectMemory
>>>> - become: (self stackValue: 2)
>>>> - with: (self stackValue: 1)
>>>> - twoWay: false
>>>> - copyHash: copyHashFlag.
>>>> - ec = PrimNoErr
>>>> - ifTrue: [self pop: argumentCount]
>>>> - ifFalse: [self primitiveFailFor: ec]!
>>>>
>>>> Item was added:
>>>> + ----- Method:
>>>> InterpreterPrimitives>>primitiveArrayBecomeOneWayCopyHashArg (in category
>>>> 'object access primitives') -----
>>>> + primitiveArrayBecomeOneWayCopyHashArg
>>>> + "Similar to primitiveArrayBecomeOneWay but accepts a third
>>>> argument deciding whether to
>>>> + copy the receiver's elements identity hashes over the
>>>> argument's elements identity hashes."
>>>> +
>>>> + | copyHashFlag ec |
>>>> + self stackTop = objectMemory trueObject
>>>> + ifTrue: [copyHashFlag := true]
>>>> + ifFalse:
>>>> + [self stackTop = objectMemory falseObject
>>>> + ifTrue: [copyHashFlag := false]
>>>> + ifFalse:
>>>> + [self primitiveFailFor:
>>>> PrimErrBadArgument.
>>>> + ^nil]].
>>>> + ec := objectMemory
>>>> + become: (self stackValue: 2)
>>>> + with: (self stackValue: 1)
>>>> + twoWay: false
>>>> + copyHash: copyHashFlag.
>>>> + ec = PrimNoErr
>>>> + ifTrue: [self pop: argumentCount]
>>>> + ifFalse: [self primitiveFailFor: ec]!
>>>>
>>>> Item was added:
>>>> + ----- Method: SimpleStackBasedCogit class>>preGenerationHook: (in
>>>> category 'translation') -----
>>>> + preGenerationHook: aCCodeGenerator
>>>> + "Define the primitiveTable initializer once all methods have
>>>> been added."
>>>> + aCCodeGenerator vmClass primitiveTable ifNotNil:
>>>> + [:bytecodeGenTable|
>>>> + aCCodeGenerator
>>>> + var: #primitiveGeneratorTable
>>>> + declareC: 'static PrimitiveDescriptor
>>>> primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1]',
>>>> + (self
>>>> tableInitializerFor: aCCodeGenerator vmClass primitiveTable
>>>> + in:
>>>> aCCodeGenerator)]!
>>>>
>>>> Item was changed:
>>>> ----- Method: StackInterpreter class>>initializePrimitiveTable (in
>>>> category 'initialization') -----
>>>> (excessive size, no diff calculated)
>>>>
>>>> Item was changed:
>>>> ----- Method: StackInterpreter>>literal:ofMethod:put: (in category
>>>> 'compiled methods') -----
>>>> literal: offset ofMethod: methodPointer put: oop
>>>> + <option: #SpurObjectMemory>
>>>> - <option: #SpurMemoryManager>
>>>> <inline: true>
>>>> objectMemory storePointer: offset + LiteralStart ofObject:
>>>> methodPointer withValue: oop
>>>> !
>>>>
>>>> Item was changed:
>>>> ----- Method: StackInterpreter>>maybeInlinePositive32BitIntegerFor:
>>>> (in category 'primitive support') -----
>>>> maybeInlinePositive32BitIntegerFor: integerValue
>>>> "N.B. will *not* cause a GC.
>>>> integerValue is interpreted as POSITIVE, e.g. as the result of
>>>> Bitmap>at:."
>>>> <notOption: #Spur64BitMemoryManager>
>>>> + <inline: #always>
>>>> <var: 'integerValue' type: #'unsigned int'>
>>>> | newLargeInteger |
>>>> self deny: objectMemory hasSixtyFourBitImmediates.
>>>> "force coercion because slang inliner sometimes incorrectly
>>>> pass a signed int without converting to unsigned"
>>>> (self cCode: [self cCoerceSimple: integerValue to: #'unsigned
>>>> int']
>>>> inSmalltalk: [integerValue bitAnd: 1 << 32 -
>>>> 1]) <= objectMemory maxSmallInteger ifTrue:
>>>> [^objectMemory integerObjectOf: integerValue].
>>>> newLargeInteger := objectMemory
>>>>
>>>> eeInstantiateSmallClassIndex: ClassLargePositiveIntegerCompactIndex
>>>> format:
>>>> (objectMemory byteFormatForNumBytes: 4)
>>>> numSlots: 1.
>>>> SPURVM
>>>> ifTrue:
>>>> ["Memory is 8 byte aligned in Spur, make sure
>>>> that oversized bytes are set to zero" "eem 4/28/2016 questionable; they
>>>> should never be read"
>>>> objectMemory storeLong32: 0 ofObject:
>>>> newLargeInteger withValue: (objectMemory byteSwapped32IfBigEndian:
>>>> integerValue).
>>>> objectMemory storeLong32: 1 ofObject:
>>>> newLargeInteger withValue: 0]
>>>> ifFalse:
>>>> [objectMemory storeLong32: 0 ofObject:
>>>> newLargeInteger withValue: (objectMemory byteSwapped32IfBigEndian:
>>>> integerValue)].
>>>> ^newLargeInteger!
>>>>
>>>> Item was changed:
>>>> ----- Method: StackInterpreter>>unfollow:atIndex: (in category
>>>> 'compiled methods') -----
>>>> unfollow: litVar atIndex: literalIndex
>>>> + <option: #SpurObjectMemory>
>>>> - <option: #SpurMemoryManager>
>>>> <inline: #never> "So rare it mustn't bulk up the common path"
>>>> | followed |
>>>> followed := objectMemory followForwarded: litVar.
>>>> self literal: literalIndex ofMethod: method put: followed.
>>>> ^followed!
>>>>
>>>> Item was changed:
>>>> ----- Method: VMBasicConstants class>>namesDefinedAtCompileTime (in
>>>> category 'C translation') -----
>>>> namesDefinedAtCompileTime
>>>> "Answer the set of names for variables that should be defined
>>>> at compile time.
>>>> Some of these get default values during simulation, and hence
>>>> get defaulted in
>>>> the various initializeMiscConstants methods. But that they
>>>> have values should
>>>> /not/ cause the code generator to do dead code elimination
>>>> based on their
>>>> default values. In particular, methods marked with <option:
>>>> ANameDefinedAtCompileTime>
>>>> will be emitted within #if
>>>> defined(ANameDefinedAtCompileTime)...#endif."
>>>> ^#( VMBIGENDIAN
>>>> IMMUTABILITY
>>>> STACKVM COGVM COGMTVM SPURVM
>>>> PharoVM
>>>> "Pharo vs Squeak"
>>>> TerfVM
>>>> "Terf vs Squeak"
>>>> EnforceAccessControl
>>>> "Newspeak"
>>>> CheckRememberedInTrampoline "IMMUTABILITY"
>>>> + BIT_IDENTICAL_FLOATING_POINT
>>>> + LLDB
>>>> "As of lldb-370.0.42 Swift-3.1, passing function parameters
>>>> to printOopsSuchThat fails with Internal error [IRForTarget]: Couldn't
>>>> rewrite one of the arguments of a function call. Turning off link time
>>>> optimization with -fno-lto has no effect. hence we define some debugging
>>>> functions as being <option: LLDB>"
>>>> - LLDB
>>>> "As of lldb-370.0.42 Swift-3.1, passing funciton parameters
>>>> to printOopsSuchThat fails with Internal error [IRForTarget]: Couldn't
>>>> rewrite one of the arguments of a function call. Turning off link time
>>>> optimization with -fno-lto has no effect. hence we define some debugging
>>>> functions as being <option: LLDB>"
>>>>
>>>> "processor related"
>>>> __ARM_ARCH__ __arm__ __arm32__ ARM32 __arm64__ ARM64
>>>> _M_I386 _X86_ i386 i486 i586 i686 __i386__ __386__ X86
>>>> I386
>>>> x86_64 __amd64 __x86_64 __amd64__ __x86_64__ _M_AMD64
>>>> _M_X64
>>>>
>>>> "Compiler brand related"
>>>> __GNUC__
>>>> _MSC_VER
>>>> __ICC
>>>>
>>>> "os related"
>>>> ACORN
>>>> __linux__
>>>> __MINGW32__
>>>> __OpenBSD__
>>>> __osf__
>>>> UNIX
>>>> WIN32 _WIN32 _WIN32_WCE
>>>> WIN64 _WIN64 _WIN64_WCE)!
>>>>
>>>>
>>
>> --
>> _,,,^..^,,,_
>> best, Eliot
>>
>
--
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20200422/5c78f9db/attachment-0001.html>
More information about the Vm-dev
mailing list