This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
can't find a register in class 'GENERAL_REGS' while reloading 'asm'
- From: Michael Haubenwallner <michael dot haubenwallner at salomon dot at>
- To: gcc-help at gcc dot gnu dot org
- Date: Thu, 19 Apr 2007 17:49:11 +0200
- Subject: can't find a register in class 'GENERAL_REGS' while reloading 'asm'
Hi,
in openssl-0.9.8e there is some inlined assembler code, which does not
compile with -fpic (or -fPIC) and -O0 on x86-linux-gnu.
$ gcc -c openssl-error.c
$ gcc -c openssl-error.c -fPIC
openssl-error.c: In function 'padlock_xcrypt_ecb':
openssl-error.c:28: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'
$ gcc -c openssl-error.c -fPIC -O1
$
It can be built without any -fpic/-fPIC, or with any optimization >= 1.
This sample is reduced from preprocessor-output of
openssl-0.9.8e/crypto/engine/eng_padlock.c on i686-pc-linux-gnu, and the
error is same for gcc-3.3.6, gcc-3.4.6, gcc-4.1.1 on i686-gentoo-linux,
as well as gcc-3.4.4 on i386 "Red Hat Enterprise Linux AS release 4
(Nahant Update 2)".
Is this a bug in that assembler-code or in the compiler, or even both ?
Thanks!
/haubi/
struct aes_key_st {
unsigned int rd_key[4 *(14 + 1)];
int rounds;
};
typedef struct aes_key_st AES_KEY;
struct padlock_cipher_data
{
unsigned char iv[16];
union { unsigned int pad[4];
struct {
int rounds:4;
int dgst:1;
int align:1;
int ciphr:1;
unsigned int keygen:1;
int interm:1;
unsigned int encdec:1;
int ksize:2;
} b;
} cword;
AES_KEY ks;
};
static inline void *padlock_xcrypt_ecb(unsigned int cnt, struct padlock_cipher_data *cdata, void *out, const void *inp)
{
void *iv;
asm volatile (
"pushl %%ebx\n"
" leal 16(%0),%%edx\n"
" leal 32(%0),%%ebx\n"
".byte 0xf3,0x0f,0xa7,0xc8" "\n"
" popl %%ebx"
: "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp)
: "0"(cdata), "1"(cnt), "2"(out), "3"(inp), "m"(*cdata)
: "edx", "cc", "memory"
);
return iv;
}
int
padlock_aes_cipher_omnivorous(unsigned char *out_arg,
const unsigned char *in_arg, unsigned int nbytes)
{
struct padlock_cipher_data *cdata;
padlock_xcrypt_ecb(nbytes/16, cdata, out_arg, in_arg);
return 1;
}