public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Assembly code parametriaztion
       [not found] <002601c2e029$7e84ab60$47ec63d9@voltan.suse.lists.egcs>
@ 2003-03-01 19:42 ` Andi Kleen
  2003-03-01 20:27   ` Piotr Wyderski
  0 siblings, 1 reply; 3+ messages in thread
From: Andi Kleen @ 2003-03-01 19:42 UTC (permalink / raw)
  To: Piotr Wyderski; +Cc: gcc

"Piotr Wyderski" <piotr.wyderski@hoga.pl> writes:

> There is very vexing lack of feature in GCC. I need to pass
> some parameters to "free-standing" assembly code (by
> free-standing I mean code placed outside any function).
> This feature is widely used by most low-level code, for
> example by Linux; interrupt/exception handlers, page tables,
> stack management etc. are usually defined this way. It's hard
> to move such code to a separate assembly file, because it
> increases redundancy (every used constant must be defined
> twice: the first time inside a C(++) header and the second time
> inside an assembly header/source file) and obliges the programmer

You can do it basically two ways (both are used in the linux kernel):

- Make your include files assembler clean, usually with moderate
use of #ifdef __ASSEMBLY__ and include them in the assembly
files. This works well for #define, but not for things like structure
offsets.

- For structure offsets or complicated expression have a separate file
  that includes the include files does something like:

	asm volatile("-- #define struct_field %0" :: "i" (offsetof(struct structure, field)));

  Compile this program with -S, then run a small postprocessor over
  the assembly file that just filters out everything behind --
  Put that into an include file and use it from your assembly.
  
  Nice thing is that it also works fine for cross compiling.
  Only tricky thing is that you have to get the dependencies right
  in the Makefile, otherwise there can be subtle failures with -j
  compilation.

-Andi

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Assembly code parametriaztion
  2003-03-01 19:42 ` Assembly code parametriaztion Andi Kleen
@ 2003-03-01 20:27   ` Piotr Wyderski
  0 siblings, 0 replies; 3+ messages in thread
From: Piotr Wyderski @ 2003-03-01 20:27 UTC (permalink / raw)
  To: Andi Kleen; +Cc: gcc


Andi Kleen wrote:

> You can do it basically two ways (both are used in the linux kernel):
>
> - Make your include files assembler clean, usually with moderate
> use of #ifdef __ASSEMBLY__ and include them in the assembly
> files. This works well for #define, but not for things like structure
> offsets.

It also doesn't work for enumerated constants, if C++ is used.
So, in fact, this solution is virtually the same as two independent
include files. The same problem with code synchronization remains
 -- you can modify a constant for C, but forget about its associated
assembly definition -- a possible source of very dangerous bugs.
My solution is able to make use of C/C++ constants directly.

> - For structure offsets or complicated expression have a separate file
>   that includes the include files does something like:
>
> asm volatile("-- #define struct_field %0" :: "i" (offsetof(struct
structure, field)));

But such a construction must be defined inside a C function...

>   Compile this program with -S, then run a small postprocessor over
>   the assembly file that just filters out everything behind --
>   Put that into an include file and use it from your assembly.

A truly comfortable solution... ;-))) All due respect (looking at
the e-mail address :-)), but Linux sources are everything but
a standard of clean code -- my built-in aesthetic monitor
throws "E_TOO_MANY_HACKS" exceptions constantly. :-)

Seriously: my set of macros allows the programmer to use it without
such combinations, you just need to type "EMIT(name,value)" and
that's all. But it's not a good solution, why can't we simply extend
GCC to accept parameters for free-standing assembly or to define
assembly constants easily, without helper functions, which are later
removed by the /**/ comments?

>   Nice thing is that it also works fine for cross compiling.

Mine too, but I don't need postprocessors.

>   Only tricky thing is that you have to get the dependencies right
>   in the Makefile, otherwise there can be subtle failures with -j
>   compilation.

A built-in mechanism would prevent such bugs...

    Best regards
    Piotr Wyderski



Serwis www.logo.hoga.pl - sciągaj bajery na telefony
Nokia, Siemens, Alcatel, Ericsson, Motorola,Samsung
------------------------------------------------------------
Promocja!!! rabat 40 % na zakup mks_vir 2003 dla klientów Connect , którzy
posiadaja kupony rabatowe.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Assembly code parametriaztion
@ 2003-03-01 19:33 Piotr Wyderski
  0 siblings, 0 replies; 3+ messages in thread
From: Piotr Wyderski @ 2003-03-01 19:33 UTC (permalink / raw)
  To: gcc


Hello.

There is very vexing lack of feature in GCC. I need to pass
some parameters to "free-standing" assembly code (by
free-standing I mean code placed outside any function).
This feature is widely used by most low-level code, for
example by Linux; interrupt/exception handlers, page tables,
stack management etc. are usually defined this way. It's hard
to move such code to a separate assembly file, because it
increases redundancy (every used constant must be defined
twice: the first time inside a C(++) header and the second time
inside an assembly header/source file) and obliges the programmer
to keep the contents of these files synchronized. GCC allows to
insert small parametrized assembly code _inside_ functions, but
not outside. It's not always possible to surround such code
with an auxilary function (to allow parametrization), because
it is unclear how the stack frame looks like. I made a simple
workaround (USED is for __attribute__((used))):

#define __EMIT(Name,Value,Line) static USED VOID __emit_const##Line()
{         \

\
    __asm__ __volatile__("*/\n\t.equ " #Name ",%c0 \n\t/*" : : "i"(Value));
\
}

#define __EMIT_AUX(Name,Value,Line) asm("/*"); __EMIT(Name,Value,Line)
asm("*/")

#define EMIT(Name,Value) __EMIT_AUX(Name,Value,__LINE__)


// Example code


namespace X {

    enum { a = 3};
}


EMIT(m_GDT,99);        // here I define m_GDT = 99
EMIT(x,X::a);                // and x = X::a = 3

asm("\tmovl $m_GDT,%eax\n\twbinvd\n");    // Free-standing code, m_GDT const
is used


G++3.2 generates the following code:


 .file "events.cpp"
#APP
 /*
#NO_APP
 .text
 .align 2
 .p2align 2,,3
 .type _Z14__emit_const20v,@function
_Z14__emit_const20v:
#APP
 */
 .equ m_GDT,99
 /*
#NO_APP
 ret
.Lfe1:
 .size _Z14__emit_const20v,.Lfe1-_Z14__emit_const20v
#APP
 */

  movl $m_GDT,%eax
  wbinvd


This way makes use of the internal code representation (to comment
out the unwanded part of code), which is obviously SICK! But this
way works and is quite comfortable to the user. Could you please
do one of the following things:

1. Make the "naked" attribute always enabled (currently it's
ARM or AVR-speciffic, don't remember...). This would
allow to remove unwanted stack frames. The same applies
to the "interrupt" attribute.

2. Unify the free-standing assembly parameter passing with
inlined assembly -- the programmer would be able to write

asm("    movl %0,%eax\n" : : "i"(156)); outside of a function.

3. Provide another mechanism for this purpose, i.e. to
pass some parameters or -- at least -- define a constant
within such code.

It would be nice to implement one of above mechanisms
in the current version of GCC. I need this feature very
much, so -- as a low-level programmer -- I can help the
GCC team to implement it properly. I see there was some
changes in the version 3.1, so I think it's necessary to finish
this process and fix the remaining inline assembly-related
problems in 3.2/3.3. Allowing only parameterless assembly
code is not a bug of course, however it's a big misfeature.

    Best regards
    Piotr Wyderski




Serwis www.logo.hoga.pl - sciągaj bajery na telefony
Nokia, Siemens, Alcatel, Ericsson, Motorola,Samsung
------------------------------------------------------------
Promocja!!! rabat 40 % na zakup mks_vir 2003 dla klientów Connect , którzy
posiadaja kupony rabatowe.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2003-03-01 20:27 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <002601c2e029$7e84ab60$47ec63d9@voltan.suse.lists.egcs>
2003-03-01 19:42 ` Assembly code parametriaztion Andi Kleen
2003-03-01 20:27   ` Piotr Wyderski
2003-03-01 19:33 Piotr Wyderski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).