help with inline asm()

help with inline asm()

Post by Phil Brow » Thu, 10 Jun 2004 01:07:04



I have what I think is a relatively clean "atomic inc" routine, that
appears to work fine.
Only trouble is, 'CC' wont compile it because it complains the function
returns a value. Could someone suggest how I could make CC as happy as cc
is?

This is x86 assembly, fyi.

#include <stdio.h>
#include <sys/types.h>
static int atomicinc(volatile uint32_t *ptr, uint32_t delta){
        asm(".volatile           \n"
            "pushl %ebx           \n"   /* save regs that we use */
            "pushl %edx           \n"   /* save regs that we use */
            "movl 16(%esp),%edx   \n"   /* pointer to var */
            "movl 20(%esp),%ebx  \n"   /* delta value */
            "movl %ebx,%eax      \n"   /* tmp copy delta to return register */
            "lock\n"
            "xaddl %ebx,(%edx)   \n"   /* add delta to *ptr var :   */
                                       /* old value xchanged to ebx  */
            "add %ebx, %eax      \n"   /* add orig value to saved delta val */
            "popl %edx            \n"   /* restore regs that we use */
            "popl %ebx            \n"   /* restore regs that we use */
            ".nonvolatile"
            );
        /* %eax is return value register */

Quote:}

 
 
 

help with inline asm()

Post by ishikaw » Thu, 10 Jun 2004 01:38:41



> I have what I think is a relatively clean "atomic inc" routine, that
> appears to work fine.
> Only trouble is, 'CC' wont compile it because it complains the function
> returns a value. Could someone suggest how I could make CC as happy as cc
> is?

> This is x86 assembly, fyi.

> #include <stdio.h>
> #include <sys/types.h>
> static int atomicinc(volatile uint32_t *ptr, uint32_t delta){
>         asm(".volatile           \n"
>             "pushl %ebx           \n"   /* save regs that we use */
>             "pushl %edx           \n"   /* save regs that we use */
>             "movl 16(%esp),%edx   \n"   /* pointer to var */
>             "movl 20(%esp),%ebx  \n"   /* delta value */
>             "movl %ebx,%eax      \n"   /* tmp copy delta to return register */
>             "lock\n"
>             "xaddl %ebx,(%edx)   \n"   /* add delta to *ptr var :   */
>                                        /* old value xchanged to ebx  */
>             "add %ebx, %eax      \n"   /* add orig value to saved delta val */
>             "popl %edx            \n"   /* restore regs that we use */
>             "popl %ebx            \n"   /* restore regs that we use */
>             ".nonvolatile"
>             );
>         /* %eax is return value register */

> }

What is CC (two capital letter 'C's) instead of cc?
Is this some sort of C++ compiler?

 
 
 

help with inline asm()

Post by Tony Walto » Thu, 10 Jun 2004 06:38:15



Quote:

> What is CC (two capital letter 'C's) instead of cc?
> Is this some sort of C++ compiler?

Yes.

--
Tony

 
 
 

help with inline asm()

Post by Seongbae Par » Fri, 11 Jun 2004 03:36:33



> I have what I think is a relatively clean "atomic inc" routine, that
> appears to work fine.
> Only trouble is, 'CC' wont compile it because it complains the function
> returns a value. Could someone suggest how I could make CC as happy as cc
> is?

> This is x86 assembly, fyi.

> #include <stdio.h>
> #include <sys/types.h>
> static int atomicinc(volatile uint32_t *ptr, uint32_t delta){
>         asm(".volatile           \n"
>             "pushl %ebx           \n"   /* save regs that we use */
>             "pushl %edx           \n"   /* save regs that we use */
>             "movl 16(%esp),%edx   \n"   /* pointer to var */
>             "movl 20(%esp),%ebx  \n"   /* delta value */
>             "movl %ebx,%eax      \n"   /* tmp copy delta to return register */
>             "lock\n"
>             "xaddl %ebx,(%edx)   \n"   /* add delta to *ptr var :   */
>                                        /* old value xchanged to ebx  */
>             "add %ebx, %eax      \n"   /* add orig value to saved delta val */
>             "popl %edx            \n"   /* restore regs that we use */
>             "popl %ebx            \n"   /* restore regs that we use */
>             ".nonvolatile"
>             );
>         /* %eax is return value register */

> }

I think you're much better off not doing it this way
- there's no clearly defined semantic for asm.

Why not just use a separate .s file ?
If you want this assembly sequence to be inlined,
the only bet in Sun compiler is to use inline template (.il)
which has a clearly defined interface semantic.

Seongbae

 
 
 

help with inline asm()

Post by Phil Brow » Fri, 11 Jun 2004 15:31:45




>> I have what I think is a relatively clean "atomic inc" routine, that
>> appears to work fine.
>> Only trouble is, 'CC' wont compile it because it complains the function
>> returns a value. Could someone suggest how I could make CC as happy as cc
>> is?
>> [code snipped]
> I think you're much better off not doing it this way
> - there's no clearly defined semantic for asm.

it works JUST FINE for 'cc'. I just need a way to make 'CC' shut up about
it. suggestions of "no, do it some completely separate way" dont help.

Quote:

> Why not just use a separate .s file ?

because I'm porting helixplayer and that's not an option.

Quote:> If you want this assembly sequence to be inlined,
> the only bet in Sun compiler is to use inline template (.il)
> which has a clearly defined interface semantic.

It's not THAT clearly defined, and it's broken when it comes to high
optimization levels by the way.
Not to mention it is disgustingly ugly.

adding    "/full/path/to/myfile.il" to every single compile line
 cc -c file.cpp /full/path/to/myfile/il
is hideous.

 
 
 

help with inline asm()

Post by UNIX admi » Fri, 11 Jun 2004 16:06:29


Quote:> I think you're much better off not doing it this way
> - there's no clearly defined semantic for asm.

> Why not just use a separate .s file ?
> If you want this assembly sequence to be inlined,
> the only bet in Sun compiler is to use inline template (.il)
> which has a clearly defined interface semantic.

Does anybody remember ASM-One on Amiga? Great macro assembler with a rich
IDE and a phenomenal de*, capable of generating executables straight
from assembler source. Is there such a thing for UNIX platforms???
 
 
 

help with inline asm()

Post by McBof » Fri, 11 Jun 2004 16:59:48





>>>I have what I think is a relatively clean "atomic inc" routine, that
>>>appears to work fine.
>>>Only trouble is, 'CC' wont compile it because it complains the function
>>>returns a value. Could someone suggest how I could make CC as happy as cc
>>>is?
>>>[code snipped]
>>I think you're much better off not doing it this way
>>- there's no clearly defined semantic for asm.
> it works JUST FINE for 'cc'. I just need a way to make 'CC' shut up about
> it. suggestions of "no, do it some completely separate way" dont help.

Hi Phil,
Could you refresh our (my!) collective memories - which CC version
are you beating your head against? Have you tried it with other
versions of Sun CC?

Quote:>>Why not just use a separate .s file ?
> because I'm porting helixplayer and that's not an option.

because the helixplayer code is idiosyncratic

cheers,
mcbofh

 
 
 

help with inline asm()

Post by Richard L. Hamilt » Fri, 11 Jun 2004 22:57:19




Quote:>> I think you're much better off not doing it this way
>> - there's no clearly defined semantic for asm.

>> Why not just use a separate .s file ?
>> If you want this assembly sequence to be inlined,
>> the only bet in Sun compiler is to use inline template (.il)
>> which has a clearly defined interface semantic.

> Does anybody remember ASM-One on Amiga? Great macro assembler with a rich
> IDE and a phenomenal de*, capable of generating executables straight
> from assembler source. Is there such a thing for UNIX platforms???

Looks to me like the assembler can no longer generate executable code
directly (I think maybe sometime back in ancient history they could if
there were no unresolve symbols.  The simplest I can get for true.s
(static (unsupported) implementation of true(1)) that looks like:

==================== cut here =================
#include <sys/syscall.h>
#include <sys/trap.h>
/* following from unistd.h, which is not suitable for include by "as" */
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
      .section  ".text"
      .global   _start
      .align    4
  _start:
      mov       SYS_exit,%o0
      mov       EXIT_SUCCESS, %g1
      ta        ST_SYSCALL
==================== cut here =================

is to use the commands:

$ as -P -D_ASM true.s
$ ld -o true true.o

Since I wanted to use some cpp symbolic constants, the -P option is to
cause "as" to preprocess with cpp; the -D_ASM is to suppress C code in
sys/syscall.h, leaving just #defines.  Note: most C include files are
_not_ suitable for including in assembler programs - these two are
exceptions, probably because the library stubs that have to be written in
assembler (well, almost - using syscall(3ucb) is mostly hokey, and at
least it would still need ST_SYSCALL from sys/trap.h 'cause syscall()
itself has to be written in assembler) need them.  After the "as" command,
the "ld" command (linker) is needed to convert the relocatable (even
though fully resolved) object into an executable.

Actually, like that, it's functionally static (using my code for the
system call rather than the library wrapper) but still technically dynamic
(even though not linked with anything).  If one wanted it truly static,
one would need the -dn option on the ld command.  The smallest I can seem
to get "true" down to is with

ld -dn -s -o true true.o

followed by

mcs -d true

but even that is a bit larger than it used to be because even though mcs
got rid of the .comment section, for some stupid reason it still left
".comment" in the .shstrtab section.  So I'm only down to 320 bytes instead
of 312 like I used to be able to get down to (both SPARC).  Darn if I know
why that happened (or what to do about it, or without a lot more research
what the absolute minimum ELF executable would look like - this is as far
as I wanted to go just out of mild curiosity).  (Anyway, the
result is a bit faster than /bin/true, not that it matters, because in
a decent shell like ksh instead of sh, "true" is a builtin.)

If you want to debug the executable, do _not_ use the -s option of "ld",
since it strips symbols.

As an alternative to -P for cpp on the "as" command, you might consider
using -m to run m4, which is probably more sensible for most assembler
than cpp anyway (there being so few existing C include files suitable
for use with assembler).

Your de* is "adb" - command driven, and none too friendly.  On
Solaris 8 and later, there's also "mdb" (and on Solaris 9 and later,
"adb" is emulated by "mdb").  "mdb" is still command driven, but a bit
less cryptic and a lot more powerful.

If you want a GUI, wrap up the "as", "ld", and "mdb" commands in a
Tcl/Tk (or dtksh) script.  But the result still isn't going to be
click monkey meets assembler, so why bother?  For that matter, I doubt
if enough people write any assembler at all anymore to recoup the cost
of developing a real assembler IDE.

--

 
 
 

help with inline asm()

Post by Seongbae Par » Sat, 12 Jun 2004 02:37:19


...

Quote:>> I think you're much better off not doing it this way
>> - there's no clearly defined semantic for asm.

> it works JUST FINE for 'cc'. I just need a way to make 'CC' shut up about
> it. suggestions of "no, do it some completely separate way" dont help.

I was half expecting this kind of reaction.
Sorry if it doesn't help you.

Quote:>> Why not just use a separate .s file ?

> because I'm porting helixplayer and that's not an option.

Frankly, I don't quite understand why it's not an option
but I'll take your word for it.

Quote:>> If you want this assembly sequence to be inlined,
>> the only bet in Sun compiler is to use inline template (.il)
>> which has a clearly defined interface semantic.

> It's not THAT clearly defined,

At least it's clearer than asm - how parameters are passed
and return values are returned, which registers you can use and etc,
since they follow whatever the calling convention defined in ABI
of the platform.

Quote:> and it's broken when it comes to high
> optimization levels by the way.

Solaris kernel and other components use .il all over the place,
and they don't have much problem. HPC folks use .il especially
libm.il all the time and we don't have much problem.
I haven't seen .il specific compiler bug for quite a while
so if you think you have seen one, please let us know
so that we can better serve you and the others.

Quote:> Not to mention it is disgustingly ugly.

> adding    "/full/path/to/myfile.il" to every single compile line
>  cc -c file.cpp /full/path/to/myfile/il
> is hideous.

The alternative is to have assembly code embedded in C file,
guarded by #ifdef if you happened to support multiple machines.

Whereas with .il, you source code is free from such,
and you just need a trivial change in the makefile
adding the path to .il to CFLAGS or CXXFLAGS.

Anyway, I'll ask c++ frontend guys to see whether this is possible
(I don't think it's possible with documented options though).
If you have any support contract with Sun,
please file an RFE through that channel.
If you don't, I'll file an RFE,
since my suggested workarounds doesn't seem to work for you.

Seongbae

 
 
 

help with inline asm()

Post by Seongbae Par » Sat, 12 Jun 2004 03:19:25



> I have what I think is a relatively clean "atomic inc" routine, that
> appears to work fine.
> Only trouble is, 'CC' wont compile it because it complains the function
> returns a value. Could someone suggest how I could make CC as happy as cc
> is?

...the actual code snipped...

...

Quote:> Anyway, I'll ask c++ frontend guys to see whether this is possible
> (I don't think it's possible with documented options though).

Just talked to those guys, and currently there's no way to do that.

Seongbae

 
 
 

help with inline asm()

Post by Seongbae Par » Sat, 12 Jun 2004 03:32:18



> I have what I think is a relatively clean "atomic inc" routine, that
> appears to work fine.
> Only trouble is, 'CC' wont compile it because it complains the function
> returns a value. Could someone suggest how I could make CC as happy as cc
> is?
> ...snipped the actual code...

> Anyway, I'll ask c++ frontend guys to see whether this is possible
> (I don't think it's possible with documented options though).

Just talked to those guys. Currently there's no way to do this.

Seongbae

 
 
 

help with inline asm()

Post by Phil Brow » Sat, 12 Jun 2004 12:51:11



> Just talked to those guys, and currently there's no way to do that.

It would be nice to at minimum have some equivalent of

NOTE(ARGSUSED)

except in this case

NOTE(RETURNSVAL)

Thats the minimum. The BETTER solution would be to have some kind of asm()
related call, like

asm_return_reg("%regnamehere");

 
 
 

help with inline asm()

Post by Phil Brow » Sat, 12 Jun 2004 12:52:19




> Hi Phil,
> Could you refresh our (my!) collective memories - which CC version
> are you beating your head against? Have you tried it with other
> versions of Sun CC?

This is sunone studio 8. something like CC V5.5