x86_64-asm: =m operand fixes
The problem was with tcctest.c:
unsigned set;
__asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
when with tcc compiled with the HAVE_SELINUX option, run with
tcc -run, it would use large addresses far beyond the 32bits
range when tcc did not use the pc-relative mode for accessing
'set' in global data memory. In fact the assembler did not
know about %rip at all.
Changes:
- memory operands use (%rax) not (%eax)
- conversion from VT_LLOCAL: use type VT_PTR
- support 'k' modifier
- support %rip register
- support X(%rip) pc-relative addresses
The test in tcctest.c is from Michael Matz.
This commit is contained in:
@ -2565,12 +2565,33 @@ static __inline__ unsigned long long inc64(unsigned long long a)
|
||||
__asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
struct struct123 {
|
||||
int a;
|
||||
int b;
|
||||
};
|
||||
struct struct1231 {
|
||||
unsigned long addr;
|
||||
};
|
||||
|
||||
unsigned long mconstraint_test(struct struct1231 *r)
|
||||
{
|
||||
unsigned long ret;
|
||||
unsigned int a[2];
|
||||
a[0] = 0;
|
||||
__asm__ volatile ("lea %2,%0; movl 4(%0),%k0; addl %2,%k0; movl $51,%2; movl $52,4%2; movl $63,%1"
|
||||
: "=&r" (ret), "=m" (a)
|
||||
: "m" (*(struct struct123 *)r->addr));
|
||||
return ret + a[0];
|
||||
}
|
||||
|
||||
unsigned int set;
|
||||
|
||||
void asm_test(void)
|
||||
{
|
||||
char buf[128];
|
||||
unsigned int val;
|
||||
struct struct123 s1;
|
||||
struct struct1231 s2 = { (unsigned long)&s1 };
|
||||
|
||||
@ -2592,6 +2613,10 @@ void asm_test(void)
|
||||
|
||||
/* 'A' constraint test */
|
||||
printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234));
|
||||
printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff));
|
||||
|
||||
s1.a = 42;
|
||||
s1.b = 43;
|
||||
printf("mconstraint: %d", mconstraint_test(&s2));
|
||||
printf(" %d %d\n", s1.a, s1.b);
|
||||
set = 0xff;
|
||||
@ -2600,9 +2625,6 @@ void asm_test(void)
|
||||
/* NOTE: we test here if C labels are correctly restored after the
|
||||
asm statement */
|
||||
goto label1;
|
||||
label2:
|
||||
__asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
|
||||
#ifdef __GNUC__ // works strange with GCC 4.3
|
||||
label2:
|
||||
__asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
|
||||
printf("set=0x%x\n", set);
|
||||
|
||||
Reference in New Issue
Block a user