예제 #1
0
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;
}
예제 #2
0
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;
}