Sender: nate AT cartsys DOT com Message-ID: <3665D2A6.D33BA4A8@cartsys.com> Date: Wed, 02 Dec 1998 15:52:06 -0800 From: Nate Eldredge X-Mailer: Mozilla 4.05 [en] (X11; I; Linux 2.0.35 i486) MIME-Version: 1.0 To: djgpp AT delorie DOT com Subject: Re: Extended ASM (Was: misc questions) References: <36634667 DOT C344DF85 AT cartsys DOT com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Reply-To: djgpp AT delorie DOT com 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