Mail Archives: djgpp/1998/12/02/19:00:09
Tal Lavi wrote:
>
> >Tal Lavi wrote:
> >>
> >> Just a couple of misc questions, thanks in advance:
> >>
> >> 1)Can I define an extended asm command as a macro,
> >> with one of the outputs value returned?
>
> >You can, using GCC's statement-expressions extension. Example:
>
> >#define TEST_BIT(n, b) ({ \
> > char c; \
> > asm("btl %1, %2; " \
> > "setcb %0" \
> > : "=rm" (c) \
> > : "rI" (b), "rm" (n)); \
> > c; \
> >})
>
> I'm sorry, but that's not really that clear.
> I checked the info's, but I'm still not that sure what "rI", "rm" does
> I *think* that rI is a register which holds an integer value, but what does
> "rm" do?
Sorry, I meant to add some explanation, but forgot to do so before
sending.
Constraints (the letters in quotes) can be combined. When you use
several, you tell the compiler that it can generate any of the options
you gave. In this case:
* "r" indicates a general register. So, the compiler could replace an
"r" operand with "%ebx", for instance.
* "m" indicates a memory reference. The compiler might generate any
sort of valid memory reference, anything from "_b" (a global variable)
to "(%ebx)" (an indirect reference).
* "I" is specific to the 386; it means a constant integer between 0 and
31, inclusive. So, for instance, "$17".
(Others you'll see frequently include "i", meaning any constant integer;
"g", which for the 386 is approximately equivalent to "rmi"; "a"-"d",
which refer to registers %eax through %edx.)
The `btl' instruction tests a bit in a longword. The longword in
question can be in a register or in memory, hence the "rm" constraint.
The bit index can either be in a register or can be given as an
immediate operand. Since it doesn't make sense for it to be greater
than 31 (there are only 32 bits in a word, numbered from 0), I chose the
"I" constraint.
> Even more vague is the extended ASM used in sys/farptr.h:
>
> {
> __asm__ __volatile__ ("movw %w0,%%fs \n"
> " .byte 0x64 \n"
> " movw %w1,(%k2)"
> :
> : "rm" (selector), "ri" (value), "r" (offset));
> }
>
> Can anyone tell me what does
> %w0 , %w1, %k2 & .byte 0x64 means?
That's some black magic. References of the form "%xn", where `x' is a
letter and `n' a number, mean "operand n, modified according to x". The
possibilities for `x' are documented only in the GCC source, in the
comment near the top of `config/i386/i386.md'. "%wn" means to name the
operand for HI-mode (half-integer, or 16-bit word). So, if GCC had
decided that %0 was %ebx, "%w0" would generate "%bx". "%kn" names it
for SI-mode (I'm not sure what it stands for, but it means 32-bit;
"standard integer" perhaps). So %eax -> %eax. I think this is the
default, so I'm not sure why the author of that function chose to
include `k'; paranoia, perhaps?
The ".byte" is GAS's pseudo-op to generate a specific byte value, rather
than assembling an instruction. So ".byte 0x64" inserts a byte of 0x64
at that point in the object code. 0x64 is the instruction prefix that
causes an "FS segment override"; the memory reference of the next
instruction will be taken relative to the FS segment, rather than the
default of DS. GAS does have a mnemonic for this prefix, so the cleaner
way to write that would be "fs \n movw ...". However, some versions of
GAS, including that in use when that file was written, had bugs which
would cause them to occasionally ignore such prefixes. Using the raw
.byte op forced it to be inserted.
> Is there a complete extended asm giude somewhere?
> The ones I found, explains only the basics.
The GCC node "Extended Asm" is the best. It refers you to the node
"Constraints", which discusses the various constraints which exist.
It's unfortunately directed mainly toward compiler hackers, but should
still be useful. The node "Machine Constraints" contains the
386-specific constraints, which are also helpful; with those and "r",
"m", "i", "g", you should be covered. Other features can be found in
the source, like I mentioned above.
Hope this helps.
--
Nate Eldredge
nate AT cartsys DOT com
- Raw text -