russellallen / self

Making the world safe for objects
http://selflanguage.org
707 stars 76 forks source link

Sparc: work around NetBSD bug in the v8 stub for `.mul` #152

Closed nbuwe closed 1 month ago

nbuwe commented 1 year ago

Sparc v7 has no multiplication instruction so a .mul function is used to do the multiplication. Typically dynamic linker detects v8 and interposes a DSO where .mul is implemented using the v8 multiplication instruction.

Unfortunately the NetBSD .mul stub doesn't follow the ABI. .mul returns the upper bits in %o1, but smul instruction returns it in %y. Nothing in the gcc generated code uses the upper half, but Self does and garbage in %o1 makes it think multiplication failed:

VM# 2 _IntMul: 2
A lookup error happened while sending the message
        primitiveFailedError:Name:
to
        2.
Subsequently, the lookup error message
        undefinedSelector:Receiver:Type:Delegatee:MethodHolder:Arguments:
was sent to
        <0>,
and was also not understood, causing the process to be aborted by the Self VM.

#0 <0x717b70 @ 0x19000180 nic # 0, pc=0x190003d0> (<error>:1): primitiveFailedError:Name: = ( | self* = 2. :arg1 = 'overflowError'. :arg2 = '_IntMul:'. delegatee = nil. selector = 'primitiveFailedError:Name:'. | 
"undefined selector error;
this method was automatically generated by the VM."
 )

    expression stack: { <0>, 'primitiveFailedError:Name:', 2, 'normal', nil, nil, <1> }
    current byte code:
        21: send: undefinedSelector:Receiver:Type:Delegatee:MethodHolder:Arguments: 6 arguments

#1 <0x717bd0 @ 0x19000000 nic # 0, pc=0x19000110> (<stdin>:1): <top level expr> = ( | self* = lobby. | 2 _IntMul: 2 )

    expression stack: { 2, 2 }
    current byte code:
        4: send: _IntMul: 1 arguments

VM# 
nbuwe commented 1 month ago

The .mul fix/workaround has been merged, so this can be closed now.