On 02/26/2015 08:13 PM, Chen Gang S wrote: > On 02/26/2015 04:04 PM, Chen Gang S wrote: >> If check fails, genrecog needs to stop and report error, so can let the >> issue be found in time. The implementation is referenced from "gcc/doc/ >> md.log": >> >> [...] >> >> whitespace >> Whitespace characters are ignored and can be inserted at any >> position except the first. This enables each alternative for >> different operands to be visually aligned in the machine >> description even if they have different number of constraints and >> modifiers. >> >> [...] >> >> '0', '1', '2', ... '9' >> [...] >> If a digit is used together with letters within the same >> alternative, the digit should come last. >> > > Oh, I guess, I misunderstood the contents above. e.g. "Up3" which > defined in aarch64 is not "matching constraint", I should skip it. >
If I really misunderstood, for me, the related patch should be: diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 81a0e79..9367d74 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -503,7 +503,8 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code) if (code == MATCH_OPERAND) { - const char constraints0 = XSTR (pattern, 2)[0]; + const char *constraints = XSTR (pattern, 2); + const char constraints0 = constraints[0]; if (!constraints_supported_in_insn_p (insn)) { @@ -537,6 +538,33 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code) "operand %d missing output reload", XINT (pattern, 0)); } + + /* For matching constraint in MATCH_OPERAND, the digit must be a + smaller number than the number of the operand that uses it in the + constraint. */ + while (1) + { + while (constraints[0] + && (constraints[0] == ' ' || constraints[0] == ',')) + constraints++; + if (!constraints[0]) + break; + + if (constraints[0] >= '0' && constraints[0] <= '9') + { + int val; + + sscanf (constraints, "%d", &val); + if (val >= XINT (pattern, 0)) + error_with_line (pattern_lineno, + "constraint digit %d is not smaller than" + " operand %d", + val, XINT (pattern, 0)); + } + + while (constraints[0] && constraints[0] != ',') + constraints++; + } } /* Allowing non-lvalues in destinations -- particularly CONST_INT -- If necessary (I guess, it is), I shall send patch v2 for it. Thanks. >> This number is allowed to be more than a single digit. If multiple >> digits are encountered consecutively, they are interpreted as a >> single decimal integer. [...] >> >> [...] >> >> [...] Moreover, the digit must be a >> smaller number than the number of the operand that uses it in the >> constraint. >> >> [...] >> >> The overall constraint for an operand is made from the letters for this >> operand from the first alternative, a comma, the letters for this >> operand from the second alternative, a comma, and so on until the last >> alternative. >> >> [...] >> >> The patch passes test: >> >> - genrecog can report the related issue when cross compiling xtensa. >> And after the related xtensa issue is fixed, genrecog will not report >> error, either. >> >> - For x86_64-unknown-linux-gnu building all-gcc, it is OK, too. >> >> >> 2015-02-26 Chen Gang <gang.chen.5...@gmail.com> >> >> * genrecog.c (validate_pattern): Check matching constraint in >> MATCH_OPERAND and use 'opnu' for all 'XINT (pattern, 0)'. >> --- >> gcc/genrecog.c | 39 +++++++++++++++++++++++++++++++++++---- >> 1 file changed, 35 insertions(+), 4 deletions(-) >> >> diff --git a/gcc/genrecog.c b/gcc/genrecog.c >> index 81a0e79..4b508e8 100644 >> --- a/gcc/genrecog.c >> +++ b/gcc/genrecog.c >> @@ -503,7 +503,9 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int >> set_code) >> >> if (code == MATCH_OPERAND) >> { >> - const char constraints0 = XSTR (pattern, 2)[0]; >> + int opnu = XINT (pattern, 0); >> + const char *constraints = XSTR (pattern, 2); >> + const char constraints0 = constraints[0]; >> >> if (!constraints_supported_in_insn_p (insn)) >> { >> @@ -525,17 +527,46 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int >> set_code) >> /* If we've only got an output reload for this operand, >> we'd better have a matching input operand. */ >> else if (constraints0 == '=' >> - && find_matching_operand (insn, XINT (pattern, 0))) >> + && find_matching_operand (insn, opnu)) >> ; >> else >> error_with_line (pattern_lineno, >> "operand %d missing in-out reload", >> - XINT (pattern, 0)); >> + opnu); >> } >> else if (constraints0 != '=' && constraints0 != '+') >> error_with_line (pattern_lineno, >> "operand %d missing output reload", >> - XINT (pattern, 0)); >> + opnu); >> + } >> + >> + /* For matching constraint in MATCH_OPERAND, the digit must be a >> + smaller number than the number of the operand that uses it in the >> + constraint. */ >> + while (1) >> + { >> + int val; >> + >> + while (constraints[0] >> + && (constraints[0] < '0' || constraints[0] > '9')) >> + constraints++; >> + if (!constraints[0]) >> + break; >> + >> + sscanf (constraints, "%d", &val); >> + while ((constraints[0] >= '0' && constraints[0] <= '9')) >> + constraints++; >> + >> + while (constraints[0] == ' ') >> + constraints++; >> + if (constraints[0] && constraints[0] != ',') >> + continue; >> + >> + if (val >= opnu) >> + error_with_line (pattern_lineno, >> + "constraint digit %d is not smaller than" >> + " operand %d", >> + val, opnu); >> } >> } >> >> > > -- Open, share, and attitude like air, water, and life which God blessed.