From 253afeed1e822965804c0f5503bac057e68f08e8 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Wed, 29 Jun 2016 18:31:45 +0200 Subject: [PATCH] inline asm: Accept 'p' constraint and 'P' template mod 'p' is conservatively the same as 'r' and 'P' as template modifier can be ignored in TCC. --- i386-asm.c | 2 ++ tccasm.c | 5 ++++- tests/tcctest.c | 9 +++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/i386-asm.c b/i386-asm.c index 064b8aa..e532911 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -1002,6 +1002,7 @@ static inline int constraint_priority(const char *str) pr = 2; break; case 'r': + case 'p': pr = 3; break; case 'N': @@ -1170,6 +1171,7 @@ ST_FUNC void asm_compute_constraints(ASMOperand *operands, } goto try_next; case 'r': + case 'p': /* A general address, for x86(64) any register is acceptable*/ /* any general register */ for(reg = 0; reg < 8; reg++) { if (!is_reg_allocated(reg)) diff --git a/tccasm.c b/tccasm.c index 6a46417..b3e9eb4 100644 --- a/tccasm.c +++ b/tccasm.c @@ -991,7 +991,10 @@ static void subst_asm_operands(ASMOperand *operands, int nb_operands, modifier = 0; if (*str == 'c' || *str == 'n' || *str == 'b' || *str == 'w' || - *str == 'h' || *str == 'k' || *str == 'q') + *str == 'h' || *str == 'k' || *str == 'q' || + /* P in GCC would add "@PLT" to symbol refs in PIC mode + Ignore this in TCC. */ + *str == 'P') modifier = *str++; index = find_constraint(operands, nb_operands, str, &str); if (index < 0) diff --git a/tests/tcctest.c b/tests/tcctest.c index 41a9a10..9230020 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -2600,6 +2600,14 @@ int fls64(unsigned long long x) } #endif +void other_constraints_test(void) +{ + unsigned long ret; + int var; + __asm__ volatile ("movq %P1,%0" : "=r" (ret) : "p" (&var)); + printf ("oc1: %d\n", ret == (unsigned long)&var); +} + unsigned int set; void asm_test(void) @@ -2633,6 +2641,7 @@ void asm_test(void) s1.b = 43; printf("mconstraint: %d", mconstraint_test(&s2)); printf(" %d %d\n", s1.a, s1.b); + other_constraints_test(); set = 0xff; sigdelset1(&set, 2); sigaddset1(&set, 16);