bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { const char *Name = Info.getConstraintStr().c_str(); // An output constraint must start with '=' or '+' if (*Name != '=' && *Name != '+') return false; if (*Name == '+') Info.setIsReadWrite(); Name++; while (*Name) { switch (*Name) { default: if (!validateAsmConstraint(Name, Info)) { // FIXME: We temporarily return false // so we can add more constraints as we hit it. // Eventually, an unknown constraint should just be treated as 'g'. return false; } case '&': // early clobber. break; case '%': // commutative. // FIXME: Check that there is a another register after this one. break; case 'r': // general register. Info.setAllowsRegister(); break; case 'm': // memory operand. case 'o': // offsetable memory operand. case 'V': // non-offsetable memory operand. case '<': // autodecrement memory operand. case '>': // autoincrement memory operand. Info.setAllowsMemory(); break; case 'g': // general register, memory operand or immediate integer. case 'X': // any operand. Info.setAllowsRegister(); Info.setAllowsMemory(); break; case ',': // multiple alternative constraint. Pass it. // Handle additional optional '=' or '+' modifiers. if (Name[1] == '=' || Name[1] == '+') Name++; break; case '?': // Disparage slightly code. case '!': // Disparage severely. case '#': // Ignore as constraint. case '*': // Ignore for choosing register preferences. break; // Pass them. } Name++; } // If a constraint allows neither memory nor register operands it contains // only modifiers. Reject it. return Info.allowsMemory() || Info.allowsRegister(); }
bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const { const char *Name = Info.getConstraintStr().c_str(); // An output constraint must start with '=' or '+' if (*Name != '=' && *Name != '+') return false; if (*Name == '+') Info.setIsReadWrite(); Name++; while (*Name) { switch (*Name) { default: if (!validateAsmConstraint(Name, Info)) { // FIXME: We temporarily return false // so we can add more constraints as we hit it. // Eventually, an unknown constraint should just be treated as 'g'. return false; } case '&': // early clobber. break; case '%': // commutative. // FIXME: Check that there is a another register after this one. break; case 'r': // general register. Info.setAllowsRegister(); break; case 'm': // memory operand. Info.setAllowsMemory(); break; case 'g': // general register, memory operand or immediate integer. case 'X': // any operand. Info.setAllowsRegister(); Info.setAllowsMemory(); break; } Name++; } return true; }