Thread overview
Access 'this' in inline assembly
Mar 07, 2011
Martin Kinkelin
Mar 07, 2011
Simon
Mar 07, 2011
Martin Kinkelin
Mar 07, 2011
Simen kjaeraas
Mar 07, 2011
Emil Madsen
Mar 07, 2011
Simon
Mar 08, 2011
bearophile
Mar 08, 2011
Brad Roberts
Mar 08, 2011
bearophile
March 07, 2011
Hi, sorry for the dumb question, but how do i get the address of an object inside a member function in inline assembly?

I have no experience with assembler yet. It seems like names of variables on the stack are treated as pointers in inline assembly, but I have no clue about how to get the address of the object itself (this and [this] do not work).

struct float4
{
    float[4] _data;

    float dot(in float4 rhs) const
    {
        float r = void;
        asm
        {
            movups XMM0, this; // need pointer to _data
            movups XMM1, rhs;
            ...
            movss r, XMM0;
        }
        return r;
    }
}

Please note that even this doesn't work:
float* ptr = cast(float*) _data.ptr;
asm { movups XMM0, ptr; }
=> 2 operands found for movups instead of the expected 1
March 07, 2011
On 07/03/2011 15:14, Martin Kinkelin wrote:
> Hi, sorry for the dumb question, but how do i get the address of an object
> inside a member function in inline assembly?
>
> I have no experience with assembler yet. It seems like names of variables on
> the stack are treated as pointers in inline assembly, but I have no clue about
> how to get the address of the object itself (this and [this] do not work).
>
> struct float4
> {
>      float[4] _data;
>
>      float dot(in float4 rhs) const
>      {
>          float r = void;
>          asm
>          {
>              movups XMM0, this; // need pointer to _data
>              movups XMM1, rhs;
>              ...
>              movss r, XMM0;
>          }
>          return r;
>      }
> }
>
> Please note that even this doesn't work:
> float* ptr = cast(float*) _data.ptr;
> asm { movups XMM0, ptr; }
> =>  2 operands found for movups instead of the expected 1

'this' is passed in EAX:

See the bit titled 'parameters'

http://www.digitalmars.com/d/2.0/abi.html

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
March 07, 2011
Thanks,

movups XMM0, [EAX];

works. The SSE version takes more than 160% of the run-time compared to the naive version though. ;)
March 07, 2011
Martin Kinkelin <noone@spam.com> wrote:

> Thanks,
>
> movups XMM0, [EAX];
>
> works. The SSE version takes more than 160% of the run-time compared to the naive
> version though. ;)

Yup. Functions using inline assembly are never inlined, so that's rarely
a good reason to use it.

-- 
Simen
March 07, 2011
On 7 March 2011 20:37, Simen kjaeraas <simen.kjaras@gmail.com> wrote:

> Martin Kinkelin <noone@spam.com> wrote:
>
>  Thanks,
>>
>> movups XMM0, [EAX];
>>
>> works. The SSE version takes more than 160% of the run-time compared to
>> the naive
>> version though. ;)
>>
>
> Yup. Functions using inline assembly are never inlined, so that's rarely a good reason to use it.
>
> --
> Simen
>

Is this just a fact of the current state of dmd, or is it by design? - and if thats the case, why?

-- 
// Yours sincerely
// Emil 'Skeen' Madsen


March 07, 2011
On 07/03/2011 19:45, Emil Madsen wrote:
> On 7 March 2011 20:37, Simen kjaeraas <simen.kjaras@gmail.com
> <mailto:simen.kjaras@gmail.com>> wrote:
>
>     Martin Kinkelin <noone@spam.com <mailto:noone@spam.com>> wrote:
>
>         Thanks,
>
>         movups XMM0, [EAX];
>
>         works. The SSE version takes more than 160% of the run-time
>         compared to the naive
>         version though. ;)
>
>
>     Yup. Functions using inline assembly are never inlined, so that's rarely
>     a good reason to use it.
>
>     --
>     Simen
>
>
> Is this just a fact of the current state of dmd, or is it by design? -
> and if thats the case, why?
>
> --
> // Yours sincerely
> // Emil 'Skeen' Madsen

It's by design. I've seen it explicitly stated somewhere (I forget) that the compiler won't optimise across asm blocks and in-lining is just a case of optimisation.

As to way, my guess is because of the way a compiler is designed and implemented.

Each stage of the compiler processes it's input, converts it to a lower level representation and then hands it off to the next stage.

Optimising across asm blocks would require reversing that process;
I think it's doable but it's highly non trivial and then you have to implement that across every supported target.

Better to spend the time improving the higher level code generation stages so people don't have to resort to ASM at all.

I guess in-lining could be separated out from the optimisation passes;
but don't hold your breath. DMD is a hodge podge of mashed together functionality, just re-factoring out in-lining would be weeks of work.

-- 
My enormous talent is exceeded only by my outrageous laziness.
http://www.ssTk.co.uk
March 08, 2011
Emil Madsen:

> > Is this just a fact of the current state of dmd, or is it by design? - and
> if thats the case, why?

It's by design, but it's a bad/wrong design. The LDC compiler has two different ways to inline asm. It's a necessary feature in a system language that want to be more than just a toy.

Bye,
bearophile
March 08, 2011
On Mon, 7 Mar 2011, bearophile wrote:

> Emil Madsen:
> 
> > > Is this just a fact of the current state of dmd, or is it by design? - and
> > if thats the case, why?
> 
> It's by design, but it's a bad/wrong design. The LDC compiler has two different ways to inline asm. It's a necessary feature in a system language that want to be more than just a toy.
> 
> Bye,
> bearophile

It's not by design.  It's a quality of implementation issue that's solvable given some time to work on it.  I intend to, eventually, unless someone has gotten to it ahead of me.

The inliner in dmd is conservative and only lines stuff it knows how to. Anything doesn't, isn't.  Nothing says it can't be taught how to inline quite a bit more than it currently does, given time to work on it.

Later,
Brad
March 08, 2011
Brad Roberts:

>It's not by design.  It's a quality of implementation issue that's solvable given some time to work on it.  I intend to, eventually, unless someone has gotten to it ahead of me.<

Good, I am glad to be wrong then.

Currently in LDC you have two different ways to tell the compiler to inline some Asm. Such syntaxes are not present in D/DMD. So do you plan to add something like those two syntaxes to D/DMD too?

One of them is this pragma: http://www.dsource.org/projects/ldc/wiki/Docs#allow_inline

int add(int a, int b) {
  pragma(allow_inline);
  asm { mov EAX, a; add EAX, b; }
}



And the other one is Inline asm expressions: http://www.dsource.org/projects/ldc/wiki/InlineAsmExpressions

That are used like this:

// store val into dst
void store(ref int dst, int val) {
  __asm("ldw r4, $1 ; stw r4, $0", "=*m,r,~{r4}", &dst, val);
}

Bye,
bearophile