www.digitalmars.com         C & C++   DMDScript  

D - syntactic sugar for asm functions

reply "Pavel Minayev" <evilone omen.ru> writes:
I remember I've raised this topic long ago, but it wasn't much discussed
and I've thought it's time to raise it again since D now has inline
asm.

What about allowing function body to be a single asm statement?

    extern(C) uint crc32(void* data, int len) asm
    {
        // assembler goes here
    }

This is a very nice feature Borland Pascal implementations have,
it makes the code somewhat neater compared to:

    extern(C) uint crc32(void* data, int len)
    {
        asm
        {
            // assembler goes here
        }
    }

Not a big change anyhow... what do you think of it?
Feb 27 2002
next sibling parent "DigitalMars" <gedumer bcpl.net> writes:
Actually... I prefer the 2nd form and think it is much more obvious as to
intent.

Gary.

Pavel Minayev <evilone omen.ru> wrote in message
news:a5ietg$p0l$1 digitaldaemon.com...
 I remember I've raised this topic long ago, but it wasn't much discussed
 and I've thought it's time to raise it again since D now has inline
 asm.

 What about allowing function body to be a single asm statement?

     extern(C) uint crc32(void* data, int len) asm
     {
         // assembler goes here
     }

 This is a very nice feature Borland Pascal implementations have,
 it makes the code somewhat neater compared to:

     extern(C) uint crc32(void* data, int len)
     {
         asm
         {
             // assembler goes here
         }
     }

 Not a big change anyhow... what do you think of it?
Feb 27 2002
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a5ietg$p0l$1 digitaldaemon.com...
 What about allowing function body to be a single asm statement?
     extern(C) uint crc32(void* data, int len) asm
     {
         // assembler goes here
     }
 This is a very nice feature Borland Pascal implementations have,
 it makes the code somewhat neater compared to:
     extern(C) uint crc32(void* data, int len)
     {
         asm
         {
             // assembler goes here
         }
     }
 Not a big change anyhow... what do you think of it?
I think the second one is better because I see an attribute as part of the interface a function presents to the world, and how it's implemented is an internal issue. In the C world, there's that declspec(naked) attribute which is just in the wrong place. Hence, in D, the naked pseudo-op appears inside the AsmStatement.
Feb 27 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a5j6os$14dc$1 digitaldaemon.com...

 I think the second one is better because I see an attribute as part of the
 interface a function presents to the world, and how it's implemented is an
 internal issue. In the C world, there's that declspec(naked) attribute
which
 is just in the wrong place. Hence, in D, the naked pseudo-op appears
inside
 the AsmStatement.
Was I speaking of naked p-op in asm blocks? No! Let it be as it is now. What I want is to have a clear way to identify that the whole function is written in assembler. There are some reasons for it other than just size of code: 1) It eliminates a nasty "missing return" bug: even though you have a RET inside your asm block, you have to add one just to stop compiler from complaining... I wonder if it gets optimized away BTW? extern(Windows) int foo(int n) { asm { enter 0, 0; mov EAX, [EBP+8]; mul EAX; leave; ret 4; } return 0; // stupid! } 2) It makes it possible for the compiler to check which calling convention is used for the function, and stop with an error if it is the default extern(D) (since it's implementation- defined, and thus shouldn't be used with assembler code). 3) It clearly states that an implicit naked pseudoop should be applied to the function.
Feb 27 2002
parent reply "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a5jaq0$16du$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a5j6os$14dc$1 digitaldaemon.com...
 I think the second one is better because I see an attribute as part of
the
 interface a function presents to the world, and how it's implemented is
an
 internal issue. In the C world, there's that declspec(naked) attribute
which
 is just in the wrong place. Hence, in D, the naked pseudo-op appears
inside
 the AsmStatement.
Was I speaking of naked p-op in asm blocks? No!
True, but it is relevant. Read on...
 Let it be as it
 is now. What I want is to have a clear way to identify that the
 whole function is written in assembler.
"naked" serves that purpose.
 There are some reasons
 for it other than just size of code:
 1) It eliminates a nasty "missing return" bug: even though
    you have a RET inside your asm block, you have to add one
    just to stop compiler from complaining... I wonder if it
    gets optimized away BTW?

         extern(Windows) int foo(int n)
         {
             asm
             {
                 enter 0, 0;
                 mov EAX, [EBP+8];
                 mul EAX;
                 leave;
                 ret 4;
             }
             return 0;    // stupid!
         }
Yes, that is stupid. Using inline asm should prevent any messages about missing return bugs. extern(Windows) int foo(int n) { asm { naked; enter 0, 0; mov EAX, n[EBP]; mul EAX; leave; ret 4; } }
 2) It makes it possible for the compiler to check which calling
    convention is used for the function, and stop with an error
    if it is the default extern(D) (since it's implementation-
    defined, and thus shouldn't be used with assembler code).
The presumption is that if you use naked inline asm, you know what you're doing and accept the risk that calling conventions differ/change. To be more forgiving of calling convention changes, do not use naked.
 3) It clearly states that an implicit naked pseudoop should
    be applied to the function.
Yes, it's an alternate way of doing that, but I don't see what it adds that's worth the special case in the grammar.
Feb 27 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Walter" <walter digitalmars.com> wrote in message
news:a5jc7h$171k$1 digitaldaemon.com...

 Let it be as it
 is now. What I want is to have a clear way to identify that the
 whole function is written in assembler.
"naked" serves that purpose.
I thought it means that programmer is responsible for prolog/epilog code, nothing more... so you could write: extern(Windows) int foo(int n) { asm { enter 0, 0; } n = (n + 2) * 3 / 4; asm { mov EAX, [EBP+8] leave ret } }
 Yes, that is stupid. Using inline asm should prevent any messages about
 missing return bugs.
Either this, or check for RET in asm blocks... but that's not very portable. So it's better to assume that this smart guy who wrote that knows what he's doing. =)
 The presumption is that if you use naked inline asm, you know what you're
 doing and accept the risk that calling conventions differ/change. To be
more
 forgiving of calling convention changes, do not use naked.
Using asm with extern(D) doesn't make sence at all, because the convention is not specified, and, in general, may vary from function to function (for optimization reasons). So it should be prohibited, IMO.
 3) It clearly states that an implicit naked pseudoop should
    be applied to the function.
Yes, it's an alternate way of doing that, but I don't see what it adds that's worth the special case in the grammar.
1 less level in the indentation =)
Feb 27 2002
parent "Walter" <walter digitalmars.com> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:a5jhsb$19i2$1 digitaldaemon.com...
 "Walter" <walter digitalmars.com> wrote in message
 news:a5jc7h$171k$1 digitaldaemon.com...
 Let it be as it
 is now. What I want is to have a clear way to identify that the
 whole function is written in assembler.
"naked" serves that purpose.
I thought it means that programmer is responsible for prolog/epilog code, nothing more... so you could write: extern(Windows) int foo(int n) { asm { enter 0, 0; } n = (n + 2) * 3 / 4; asm { mov EAX, [EBP+8] leave ret } }
Yes, you're correct, but I think you'll also see that naked serves the purpose of indicating the whole thing is in assembly, too.
 Yes, that is stupid. Using inline asm should prevent any messages about
 missing return bugs.
Either this, or check for RET in asm blocks... but that's not very portable. So it's better to assume that this smart guy who wrote that knows what he's doing. =)
There are many ways to return using asm, not just with a RET, so the assumption is the programmer knows what he's doing.
Feb 27 2002