diff options
Diffstat (limited to 'gcc/recog.c')
-rw-r--r-- | gcc/recog.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/recog.c b/gcc/recog.c index b81214c..e2caf9859 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -1620,6 +1620,50 @@ decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs, return ASM_OPERANDS_TEMPLATE (asmop); } +/* Parse inline assembly string STRING and determine which operands are + referenced by % markers. For the first NOPERANDS operands, set USED[I] + to true if operand I is referenced. + + This is intended to distinguish barrier-like asms such as: + + asm ("" : "=m" (...)); + + from real references such as: + + asm ("sw\t$0, %0" : "=m" (...)); */ + +void +get_referenced_operands (const char *string, bool *used, + unsigned int noperands) +{ + memset (used, 0, sizeof (bool) * noperands); + const char *p = string; + while (*p) + switch (*p) + { + case '%': + p += 1; + /* A letter followed by a digit indicates an operand number. */ + if (ISALPHA (p[0]) && ISDIGIT (p[1])) + p += 1; + if (ISDIGIT (*p)) + { + char *endptr; + unsigned long opnum = strtoul (p, &endptr, 10); + if (endptr != p && opnum < noperands) + used[opnum] = true; + p = endptr; + } + else + p += 1; + break; + + default: + p++; + break; + } +} + /* Check if an asm_operand matches its constraints. Return > 0 if ok, = 0 if bad, < 0 if inconclusive. */ |