tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] asmtest problem


From: grischka
Subject: Re: [Tinycc-devel] asmtest problem
Date: Sun, 20 Nov 2016 14:09:43 +0100
User-agent: Thunderbird 2.0.0.23 (Windows/20090812)

Michael Matz wrote:
Hello grischka,

On Wed, 19 Oct 2016, grischka wrote:

There seems to be a asm problem in tcctest.c with the bts
instruction on x86-64, which crashes it under circumstances.

    __asm__("bts %1,%0" : "=m"(*pset) : "Ir"(_sig - 1) : "cc");

From dump:
  3d:   8b 45 d0                mov    -0x30(%rbp),%eax <-- address
  Here it should load the addres into %rax, not %eax

Ah yes, that one. The attached patch should solve this, which also is part of that mythical larger series that makes us compile the linux x86-64 kernel.

Ok, I added some of this.  Also support for X(%rip) addresses, currently
without any checks for usage of %rip in invalid context.

http://repo.or.cz/tinycc.git/commitdiff/4a3741bf02eb51c377312bdabc979e5ccbf5bf89

Ready for release 0.9.27 soon? ;)

--- grischka



Ciao,
Michael.

commit 70a1dc38908b6ff679f15cf033828afda885d35f
Author: Michael Matz <address@hidden>
Date:   Wed Jun 29 18:06:40 2016 +0200

    inline asm: Fix 'm' constraints
See testcase. The m constraint actually passes the address
    and hence is of pointer type.

diff --git a/i386-asm.c b/i386-asm.c
index c0dd435..cc73320 100644
--- a/i386-asm.c
+++ b/i386-asm.c
@@ -1291,7 +1291,12 @@ ST_FUNC void subst_asm_operand(CString *add_str,
         if (reg >= VT_CONST)
             tcc_error("internal compiler error");
         snprintf(buf, sizeof(buf), "(%%%s)",
-                 get_tok_str(TOK_ASM_eax + reg, NULL));
+#ifdef TCC_TARGET_X86_64
+                 get_tok_str(TOK_ASM_rax + reg, NULL)
+#else
+                 get_tok_str(TOK_ASM_eax + reg, NULL)
+#endif
+                );
         cstr_cat(add_str, buf, -1);
     } else {
         /* register case */
@@ -1392,7 +1397,8 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int 
nb_operands,
                        output cases) */
                     SValue sv;
                     sv = *op->vt;
-                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL;
+                    sv.r = (sv.r & ~VT_VALMASK) | VT_LOCAL | VT_LVAL;
+                   sv.type.t = VT_PTR;
                     load(op->reg, &sv);
                 } else if (i >= nb_outputs || op->is_rw) {
                     /* load value in register */
diff --git a/tccasm.c b/tccasm.c
index 55feecf..ad9580a 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -1043,7 +1043,8 @@ static void parse_asm_operands(ASMOperand *operands, int 
*nb_operands_ptr,
             skip('(');
             gexpr();
             if (is_output) {
-                test_lvalue();
+               if (!(vtop->type.t & VT_ARRAY))
+                   test_lvalue();
             } else {
                 /* we want to avoid LLOCAL case, except when the 'm'
                    constraint is used. Note that it may come from
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 28ba263..0922d77 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -2583,12 +2583,33 @@ int fls64(unsigned long long x)
 }
 #endif
+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 ("leaq %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 };
printf("inline asm:\n"); @@ -2610,6 +2631,10 @@ void asm_test(void)
     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;
     sigdelset1(&set, 2);
     sigaddset1(&set, 16);

_______________________________________________
Tinycc-devel mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/tinycc-devel





reply via email to

[Prev in Thread] Current Thread [Next in Thread]