bool StackmapSpecial::isValidImpl( unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs, Inst& inst) { StackmapValue* value = inst.origin->as<StackmapValue>(); ASSERT(value); // Check that insane things have not happened. ASSERT(inst.args.size() >= numIgnoredAirArgs); ASSERT(value->children().size() >= numIgnoredB3Args); // For the Inst to be valid, it needs to have the right number of arguments. if (inst.args.size() - numIgnoredAirArgs < value->children().size() - numIgnoredB3Args) return false; // Regardless of constraints, stackmaps have some basic requirements for their arguments. For // example, you can't have a non-FP-offset address. This verifies those conditions as well as the // argument types. for (unsigned i = 0; i < value->children().size() - numIgnoredB3Args; ++i) { Value* child = value->child(i + numIgnoredB3Args); Arg& arg = inst.args[i + numIgnoredAirArgs]; if (!isArgValidForValue(arg, child)) return false; } // The number of constraints has to be no greater than the number of B3 children. ASSERT(value->m_reps.size() <= value->children().size()); // Verify any explicitly supplied constraints. for (unsigned i = numIgnoredB3Args; i < value->m_reps.size(); ++i) { ValueRep& rep = value->m_reps[i]; Arg& arg = inst.args[i - numIgnoredB3Args + numIgnoredAirArgs]; if (!isArgValidForRep(code(), arg, rep)) return false; } return true; }
bool StackmapSpecial::isValidImpl( unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs, Inst& inst) { StackmapValue* value = inst.origin->as<StackmapValue>(); ASSERT(value); // Check that insane things have not happened. ASSERT(inst.args.size() >= numIgnoredAirArgs); ASSERT(value->children().size() >= numIgnoredB3Args); // For the Inst to be valid, it needs to have the right number of arguments. if (inst.args.size() - numIgnoredAirArgs != value->children().size() - numIgnoredB3Args) return false; // Regardless of constraints, stackmaps have some basic requirements for their arguments. For // example, you can't have a non-FP-offset address. This verifies those conditions as well as the // argument types. for (unsigned i = 0; i < inst.args.size() - numIgnoredAirArgs; ++i) { Value* child = value->child(i + numIgnoredB3Args); Arg& arg = inst.args[i + numIgnoredAirArgs]; switch (arg.kind()) { case Arg::Tmp: case Arg::Imm: case Arg::Imm64: case Arg::Stack: case Arg::CallArg: break; // OK case Arg::Addr: if (arg.base() != Tmp(GPRInfo::callFrameRegister) && arg.base() != Tmp(MacroAssembler::stackPointerRegister)) return false; break; default: return false; } Arg::Type type = Arg::typeForB3Type(child->type()); if (!arg.isType(type)) return false; } // The number of constraints has to be no greater than the number of B3 children. ASSERT(value->m_reps.size() <= value->children().size()); // Verify any explicitly supplied constraints. for (unsigned i = numIgnoredB3Args; i < value->m_reps.size(); ++i) { ValueRep& rep = value->m_reps[i]; Arg& arg = inst.args[i - numIgnoredB3Args + numIgnoredAirArgs]; switch (rep.kind()) { case ValueRep::Any: // We already verified this above. break; case ValueRep::SomeRegister: if (!arg.isTmp()) return false; break; case ValueRep::Register: if (arg != Tmp(rep.reg())) return false; break; case ValueRep::Stack: // This is not a valid input representation. ASSERT_NOT_REACHED(); break; case ValueRep::StackArgument: if (arg == Arg::callArg(rep.offsetFromSP())) break; if (arg.isAddr() && code().frameSize()) { if (arg.base() == Tmp(GPRInfo::callFrameRegister) && arg.offset() == rep.offsetFromSP() - code().frameSize()) break; if (arg.base() == Tmp(MacroAssembler::stackPointerRegister) && arg.offset() == rep.offsetFromSP()) break; } return false; case ValueRep::Constant: // This is not a valid input representation. ASSERT_NOT_REACHED(); break; } } return true; }