bool MIParser::verifyImplicitOperands( ArrayRef<MachineOperandWithLocation> Operands, const MCInstrDesc &MCID) { if (MCID.isCall()) // We can't verify call instructions as they can contain arbitrary implicit // register and register mask operands. return false; // Gather all the expected implicit operands. SmallVector<MachineOperand, 4> ImplicitOperands; if (MCID.ImplicitDefs) for (const uint16_t *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs) ImplicitOperands.push_back( MachineOperand::CreateReg(*ImpDefs, true, true)); if (MCID.ImplicitUses) for (const uint16_t *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses) ImplicitOperands.push_back( MachineOperand::CreateReg(*ImpUses, false, true)); const auto *TRI = MF.getSubtarget().getRegisterInfo(); assert(TRI && "Expected target register info"); size_t I = ImplicitOperands.size(), J = Operands.size(); while (I) { --I; if (J) { --J; const auto &ImplicitOperand = ImplicitOperands[I]; const auto &Operand = Operands[J].Operand; if (ImplicitOperand.isIdenticalTo(Operand)) continue; if (Operand.isReg() && Operand.isImplicit()) { return error(Operands[J].Begin, Twine("expected an implicit register operand '") + printImplicitRegisterFlag(ImplicitOperand) + " %" + getRegisterName(TRI, ImplicitOperand.getReg()) + "'"); } } // TODO: Fix source location when Operands[J].end is right before '=', i.e: // insead of reporting an error at this location: // %eax = MOV32r0 // ^ // report the error at the following location: // %eax = MOV32r0 // ^ return error(J < Operands.size() ? Operands[J].End : Token.location(), Twine("missing implicit register operand '") + printImplicitRegisterFlag(ImplicitOperands[I]) + " %" + getRegisterName(TRI, ImplicitOperands[I].getReg()) + "'"); } return false; }
static bool HasImplicitCPSRDef(const MCInstrDesc &MCID) { for (const uint16_t *Regs = MCID.getImplicitDefs(); *Regs; ++Regs) if (*Regs == ARM::CPSR) return true; return false; }