gcc-4 inline assembler question (no register in class 'GENERAL_REGS' error)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

while trying to build qemu, I see errors in the inline
assembler. Investigating it shows that the problem is caused by code
like:


-----
typedef unsigned int	size_t;

#define offsetof(TYPE, MEMBER)  ((size_t) &((TYPE *)0)->MEMBER)
#define Xoffsetof(TYPE, MEMBER) (*(unsigned char*)offsetof(TYPE, MEMBER))

typedef struct {
    unsigned long regs[8];
} CPUState;

int foo()
{
  
  asm("    fs movl %0, %%eax\n"
      "    fs movl %1, %%ebx\n"
      "    fs movl %2, %%ecx\n"
      "    fs movl %3, %%edx\n"
      "    fs movl %4, %%esp\n"
      "    fs movl %5, %%ebp\n"
      "    fs movl %6, %%esi\n"   // **
      :
      : "m" (Xoffsetof(CPUState, regs[0])),
	"m" (Xoffsetof(CPUState, regs[1])),
	"m" (Xoffsetof(CPUState, regs[2])),
	"m" (Xoffsetof(CPUState, regs[3])),
	"m" (Xoffsetof(CPUState, regs[4])),
	"m" (Xoffsetof(CPUState, regs[5])), // **
	"m" (Xoffsetof(CPUState, regs[6]))
    );
}
-------

| $ gcc -c foo.c
| foo.c: In function 'foo':
| foo.c:11: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'


gcc32 does not have problems with it and generates code like:

| $ gcc32 -c foo.c
| $ objdump -d foo.o
| 00000000 <foo>:
|    0:   55                      push   %ebp
|    1:   89 e5                   mov    %esp,%ebp
|    3:   64 a1 00 00 00 00       mov    %fs:0x0,%eax
|    9:   64 8b 1d 04 00 00 00    mov    %fs:0x4,%ebx
|   10:   64 8b 0d 08 00 00 00    mov    %fs:0x8,%ecx
|   17:   64 8b 15 0c 00 00 00    mov    %fs:0xc,%edx
|   1e:   64 8b 25 10 00 00 00    mov    %fs:0x10,%esp
|   25:   64 8b 2d 14 00 00 00    mov    %fs:0x14,%ebp
|   2c:   64 8b 35 18 00 00 00    mov    %fs:0x18,%esi
|   33:   c9                      leave  
|   34:   c3                      ret   


Further investigations show that the removal of the lines marked with '**'
lets it succeed with gcc-4 also, and generates correct but ineffizient
code:

| $ gcc -c foo.c
| $ objdump -d foo.o
| 00000000 <foo>:
|    0:   55                      push   %ebp
|    1:   89 e5                   mov    %esp,%ebp
|    3:   57                      push   %edi
|    4:   56                      push   %esi
|    5:   53                      push   %ebx
|    6:   bf 00 00 00 00          mov    $0x0,%edi
|    b:   bb 04 00 00 00          mov    $0x4,%ebx
|   10:   be 08 00 00 00          mov    $0x8,%esi
|   15:   b9 0c 00 00 00          mov    $0xc,%ecx
|   1a:   ba 10 00 00 00          mov    $0x10,%edx
|   1f:   b8 18 00 00 00          mov    $0x18,%eax
|   24:   64 8b 07                mov    %fs:(%edi),%eax
|   27:   64 8b 1b                mov    %fs:(%ebx),%ebx
|   2a:   64 8b 0e                mov    %fs:(%esi),%ecx
|   2d:   64 8b 11                mov    %fs:(%ecx),%edx
|   30:   64 8b 22                mov    %fs:(%edx),%esp
|   33:   64 8b 28                mov    %fs:(%eax),%ebp
|   36:   5b                      pop    %ebx
|   37:   5e                      pop    %esi
|   38:   5f                      pop    %edi
|   39:   c9                      leave  
|   3a:   c3                      ret    


This explains why gcc-4 complains about the missing regs: it tries to
load the immediate offset values into general regs first and accesses
the memory based on them then. With more than 6 variables there are not
enough regs available.

Now my question: what is the correct way to achieve the first object
code with inline assembler? Using the specific registers as machine
constraints does not work as the posted assembly block happens within
more complex code in the real qemu code.

I tried things like

| asm("fs movl (%0),%%ebx" : : "i"(offsetof(CPUState, regs[1])))

already but it generates the wrong code ('mov    %fs:0x0,%ebx').




Enrico

Attachment: pgpFKKvy00DTk.pgp
Description: PGP signature

-- 
fedora-devel-list mailing list
fedora-devel-list@xxxxxxxxxx
http://www.redhat.com/mailman/listinfo/fedora-devel-list

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Fedora Announce]     [Fedora Kernel]     [Fedora Testing]     [Fedora Formulas]     [Fedora PHP Devel]     [Kernel Development]     [Fedora Legacy]     [Fedora Maintainers]     [Fedora Desktop]     [PAM]     [Red Hat Development]     [Gimp]     [Yosemite News]
  Powered by Linux