kernel/acpica/common/dmswitch.c
/*******************************************************************************
 *
 * FUNCTION:    AcpiDmIsSwitchBlock
 *
 * PARAMETERS:  Op              - While Object
 *
 * RETURN:      TRUE if While block can be converted to a Switch/Case block
 *
 * DESCRIPTION: Determines if While block is a Switch/Case statement. Modifies
 *              parse tree to allow for Switch/Case disassembly during walk.
 *
 * EXAMPLE: Example of parse tree to be converted
 *
 *    While
 *        One
 *        Store
 *            ByteConst
 *             -NamePath-
 *        If
 *            LEqual
 *                -NamePath-
 *                Zero
 *            Return
 *                One
 *        Else
 *            Return
 *                WordConst
 *        Break
 *
 ******************************************************************************/
AcpiDmIsSwitchBlock
PARAMETERS:  Op              - While Object

TRUE if While block can be converted to a Switch/Case block

Determines if While block is a Switch/Case statement. Modifies
parse tree to allow for Switch/Case disassembly during walk.

Example of parse tree to be converted


AcpiDmIsSwitchBlock PARAMETERS : Op - While Object TRUE if While block can be converted to a Switch / Case block Determines if While block is a Switch / Case statement . Modifies parse tree to allow for Switch / Case disassembly during walk . Example of parse tree to be converted
BOOLEAN
AcpiDmIsSwitchBlock (
    ACPI_PARSE_OBJECT       *Op,
    char                    **Temp)
{
    ACPI_PARSE_OBJECT       *OneOp;
    ACPI_PARSE_OBJECT       *StoreOp;
    ACPI_PARSE_OBJECT       *NamePathOp;
    ACPI_PARSE_OBJECT       *PredicateOp;
    ACPI_PARSE_OBJECT       *CurrentOp;
    ACPI_PARSE_OBJECT       *TempOp;
    OneOp = AcpiPsGetArg (Op, 0);
    if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP))
    {
        return (FALSE);
    }
    StoreOp = OneOp->Common.Next;
    if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP))
    {
        return (FALSE);
    }
    NamePathOp = AcpiPsGetArg (StoreOp, 1);
    if (!NamePathOp ||
        (NamePathOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
    {
        return (FALSE);
    }
    if (strncmp ((char *) (NamePathOp->Common.Value.Name), "_T_", 3))
    {
        return (FALSE);
    }
    *Temp = (char *) (NamePathOp->Common.Value.Name);
    OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
    PredicateOp = AcpiPsGetArg (StoreOp, 0);
    PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
    PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
    NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
    CurrentOp = StoreOp->Common.Next;
    while (AcpiDmIsCaseBlock (CurrentOp))
    {
        if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
        {
            CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
            CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        }
        CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
        TempOp = AcpiPsGetArg (CurrentOp, 0);
        switch (TempOp->Common.AmlOpcode)
        {
        case (AML_LOGICAL_EQUAL_OP):
            TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
            TempOp = AcpiPsGetArg (TempOp, 0);
            TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
            PredicateOp = TempOp->Common.Next;
            PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
            PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
            break;
        case (AML_LOGICAL_NOT_OP):
            TempOp = AcpiPsGetArg (TempOp, 0);
            TempOp = AcpiPsGetArg (TempOp, 0);
            PredicateOp = AcpiPsGetArg (TempOp, 0);
            PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
            TempOp = AcpiPsGetArg (CurrentOp, 1);
            CurrentOp->Common.Value.Arg = PredicateOp;
            PredicateOp->Common.Parent = CurrentOp;
            PredicateOp->Common.Next = TempOp;
            break;
        default:
            break;
        }
        CurrentOp = CurrentOp->Common.Next;
    }
    if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
    {
        CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT;
    }
    CurrentOp = StoreOp->Common.Next->Common.Next;
    if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
    {
        CurrentOp = CurrentOp->Common.Next;
    }
    CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    return (TRUE);
}
BOOLEAN AcpiDmIsSwitchBlock ( ACPI_PARSE_OBJECT * Op , char * * Temp ) { ACPI_PARSE_OBJECT * OneOp ; ACPI_PARSE_OBJECT * StoreOp ; ACPI_PARSE_OBJECT * NamePathOp ; ACPI_PARSE_OBJECT * PredicateOp ; ACPI_PARSE_OBJECT * CurrentOp ; ACPI_PARSE_OBJECT * TempOp ; OneOp = AcpiPsGetArg ( Op , 0 ) ; if ( ! OneOp || ( OneOp -> Common . AmlOpcode != AML_ONE_OP ) ) { return ( FALSE ) ; } StoreOp = OneOp -> Common . Next ; if ( ! StoreOp || ( StoreOp -> Common . AmlOpcode != AML_STORE_OP ) ) { return ( FALSE ) ; } NamePathOp = AcpiPsGetArg ( StoreOp , 1 ) ; if ( ! NamePathOp || ( NamePathOp -> Common . AmlOpcode != AML_INT_NAMEPATH_OP ) ) { return ( FALSE ) ; } if ( strncmp ( ( char * ) ( NamePathOp -> Common . Value . Name ) , " " , 3 ) ) { return ( FALSE ) ; } * Temp = ( char * ) ( NamePathOp -> Common . Value . Name ) ; OneOp -> Common . DisasmFlags |= ACPI_PARSEOP_IGNORE ; StoreOp -> Common . DisasmOpcode = ACPI_DASM_IGNORE_SINGLE ; PredicateOp = AcpiPsGetArg ( StoreOp , 0 ) ; PredicateOp -> Common . DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE ; PredicateOp -> Common . DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST ; NamePathOp -> Common . DisasmFlags = ACPI_PARSEOP_IGNORE ; CurrentOp = StoreOp -> Common . Next ; while ( AcpiDmIsCaseBlock ( CurrentOp ) ) { if ( CurrentOp -> Common . AmlOpcode == AML_ELSE_OP ) { CurrentOp -> Common . DisasmOpcode = ACPI_DASM_CASE ; CurrentOp = AcpiPsGetArg ( CurrentOp , 0 ) ; } CurrentOp -> Common . DisasmOpcode = ACPI_DASM_CASE ; TempOp = AcpiPsGetArg ( CurrentOp , 0 ) ; switch ( TempOp -> Common . AmlOpcode ) { case ( AML_LOGICAL_EQUAL_OP ) : TempOp -> Common . DisasmOpcode = ACPI_DASM_IGNORE_SINGLE ; TempOp = AcpiPsGetArg ( TempOp , 0 ) ; TempOp -> Common . DisasmFlags = ACPI_PARSEOP_IGNORE ; PredicateOp = TempOp -> Common . Next ; PredicateOp -> Common . DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE ; PredicateOp -> Common . DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST ; break ; case ( AML_LOGICAL_NOT_OP ) : TempOp = AcpiPsGetArg ( TempOp , 0 ) ; TempOp = AcpiPsGetArg ( TempOp , 0 ) ; PredicateOp = AcpiPsGetArg ( TempOp , 0 ) ; PredicateOp -> Common . DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST ; TempOp = AcpiPsGetArg ( CurrentOp , 1 ) ; CurrentOp -> Common . Value . Arg = PredicateOp ; PredicateOp -> Common . Parent = CurrentOp ; PredicateOp -> Common . Next = TempOp ; break ; default : break ; } CurrentOp = CurrentOp -> Common . Next ; } if ( CurrentOp && CurrentOp -> Common . AmlOpcode == AML_ELSE_OP ) { CurrentOp -> Common . DisasmOpcode = ACPI_DASM_DEFAULT ; } CurrentOp = StoreOp -> Common . Next -> Common . Next ; if ( CurrentOp -> Common . AmlOpcode == AML_ELSE_OP ) { CurrentOp = CurrentOp -> Common . Next ; } CurrentOp -> Common . DisasmFlags |= ACPI_PARSEOP_IGNORE ; return ( TRUE ) ; }
FUNCTION:    AcpiDmIsSwitchBlock
 PARAMETERS:  Op              - While Object
FUNCTION : AcpiDmIsSwitchBlock PARAMETERS : Op - While Object
/* Check for One Op Predicate */ /* Check for Store Op */ /* Check for Name Op with _T_ string */ /* This is a Switch/Case control block */ /* Ignore the One Op Predicate */ /* Ignore the Store Op, but not the children */ /*
     * First arg of Store Op is the Switch condition.
     * Mark it as a Switch predicate and as a parameter list for paren
     * closing and correct indentation.
     */ /* Ignore the Name Op */ /* Remaining opcodes are the Case statements (If/ElseIf's) */ /* Block is a Case structure */ /* ElseIf */ /* If */ /*
         * Mark the parse tree for Case disassembly. There are two
         * types of Case statements. The first type of statement begins with
         * an LEqual. The second starts with an LNot and uses a Match statement
         * on a Package of constants.
         */ /* Ignore just the LEqual Op */ /* Ignore the NamePath Op */ /*
             * Second arg of LEqual will be the Case predicate.
             * Mark it as a predicate and also as a parameter list for paren
             * closing and correct indentation.
             */ /*
             * The Package will be the predicate of the Case statement.
             * It's under:
             *            LNOT
             *                LEQUAL
             *                    MATCH
             *                        PACKAGE
             */ /* Get the LEqual Op from LNot */ /* Get the Match Op from LEqual */ /* Get the Package Op from Match */ /* Mark as parameter list for paren closing */ /*
             * The Package list would be too deeply indented if we
             * chose to simply ignore the all the parent opcodes, so
             * we rearrange the parse tree instead.
             */ /*
             * Save the second arg of the If/Else Op which is the
             * block code of code for this Case statement.
             */ /*
             * Move the Package Op to the child (predicate) of the
             * Case statement.
             */ /* Add the block code */ /* Should never get here */ /* Advance to next Case block */ /* If CurrentOp is now an Else, then this is a Default block */ /*
     * From the first If advance to the Break op. It's possible to
     * have an Else (Default) op here when there is only one Case
     * statement, so check for it.
     */ /* Ignore the Break Op */