static inline int
index_register_operand_1 (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
#line 542 "../.././gcc/config/i386/predicates.md"
{
  if (GET_CODE (op) == SUBREG)
    op = SUBREG_REG (op);
  if (reload_in_progress || reload_completed)
    return REG_OK_FOR_INDEX_STRICT_P (op);
  else
    return REG_OK_FOR_INDEX_NONSTRICT_P (op);
}
示例#2
0
int
legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
{
    struct avm2_address parts;
    rtx base, index, disp;
    HOST_WIDE_INT scale;
    const char *reason = NULL;
    rtx reason_rtx = NULL_RTX;

    if (avm2_decompose_address (addr, &parts) <= 0)
    {
        reason = "decomposition failed";
        goto report_error;
    }

    base = parts.base;
    index = parts.index;
    disp = parts.disp;
    scale = parts.scale;

    /* Validate base register.

       Don't allow SUBREG's that span more than a word here.  It can lead to spill
       failures when the base is one word out of a two word structure, which is
       represented internally as a DImode int.  */

    if (base)
    {
        rtx reg;
        reason_rtx = base;

        if (REG_P (base))
            reg = base;
        else if (GET_CODE (base) == SUBREG
                 && REG_P (SUBREG_REG (base))
                 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (base)))
                 <= UNITS_PER_WORD)
            reg = SUBREG_REG (base);
        else
        {
            reason = "base is not a register";
            goto report_error;
        }

        if (GET_MODE (base) != Pmode)
        {
            reason = "base is not in Pmode";
            goto report_error;
        }

        if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
                || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (reg)))
        {
            reason = "base is not valid";
            goto report_error;
        }
    }

    /* Validate index register.

       Don't allow SUBREG's that span more than a word here -- same as above.  */

    if (index)
    {
        rtx reg;
        reason_rtx = index;

        if (REG_P (index))
            reg = index;
        else if (GET_CODE (index) == SUBREG
                 && REG_P (SUBREG_REG (index))
                 && GET_MODE_SIZE (GET_MODE (SUBREG_REG (index)))
                 <= UNITS_PER_WORD)
            reg = SUBREG_REG (index);
        else
        {
            reason = "index is not a register";
            goto report_error;
        }

        if (GET_MODE (index) != Pmode)
        {
            reason = "index is not in Pmode";
            goto report_error;
        }

        if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
                || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (reg)))
        {
            reason = "index is not valid";
            goto report_error;
        }
    }

    /* Validate scale factor.  */
    if (scale != 1)
    {
        reason_rtx = GEN_INT (scale);
        if (!index)
        {
            reason = "scale without index";
            goto report_error;
        }

        if (scale != 2 && scale != 4 && scale != 8)
        {
            reason = "scale is not a valid multiplier";
            goto report_error;
        }
    }

    /* Validate displacement.  */
    if (disp)
    {
        reason_rtx = disp;

        if (GET_CODE (disp) == CONST
                && GET_CODE (XEXP (disp, 0)) == UNSPEC)
            switch (XINT (XEXP (disp, 0), 1))
            {
            default:
                reason = "invalid address unspec";
                goto report_error;
            }

        else if (SYMBOLIC_CONST (disp)
                 && (flag_pic))
        {
            /* APPLE LOCAL end dynamic-no-pic */

            /* This code used to verify that a symbolic pic displacement
            includes the pic_offset_table_rtx register.

            While this is good idea, unfortunately these constructs may
            be created by "adds using lea" optimization for incorrect
            code like:

            int a;
            int foo(int i)
             {
               return *(&a+i);
             }

            This code is nonsensical, but results in addressing
            GOT table with pic_offset_table_rtx base.  We can't
            just refuse it easily, since it gets matched by
            "addsi3" pattern, that later gets split to lea in the
            case output register differs from input.  While this
            can be handled by separate addsi pattern for this case
            that never results in lea, this seems to be easier and
            correct fix for crash to disable this test.  */
        }
        else if (GET_CODE (disp) != LABEL_REF
                 && GET_CODE (disp) != CONST_INT
                 && (GET_CODE (disp) != CONST
                     || !legitimate_constant_p (disp))
                 && (GET_CODE (disp) != SYMBOL_REF
                     || !legitimate_constant_p (disp)))
        {
            reason = "displacement is not constant";
            goto report_error;
        }
    }
    return TRUE;

report_error:
    return FALSE;
}