/******************************************************************************
 *
 * Module Name: adwalk - Disassembler routines for switch statements
 *
 *****************************************************************************/

/*
 * Copyright (C) 2000 - 2023, Intel Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include "acpi.h"
#include "accommon.h"
#include "acparser.h"
#include "amlcode.h"
#include "acdisasm.h"
#include "acdispat.h"
#include "acnamesp.h"
#include "acapps.h"


#define _COMPONENT          ACPI_CA_DISASSEMBLER
        ACPI_MODULE_NAME    ("dmswitch")

static BOOLEAN
AcpiDmIsSwitchBlock (
    ACPI_PARSE_OBJECT       *Op,
    char                    **Temp);

static BOOLEAN
AcpiDmIsCaseBlock (
    ACPI_PARSE_OBJECT       *Op);


/*******************************************************************************
 *
 * FUNCTION:    AcpiDmProcessSwitch
 *
 * PARAMETERS:  Op              - Object to be examined
 *
 * RETURN:      ACPI_STATUS
 *
 * DESCRIPTION: Walk function to create a list of all temporary (_T_) objects.
 *              If a While loop is found that can be converted to a Switch, do
 *              the conversion, remove the temporary name from the list, and
 *              mark the parse op with an IGNORE flag.
 *
 ******************************************************************************/

ACPI_STATUS
AcpiDmProcessSwitch (
    ACPI_PARSE_OBJECT       *Op)
{
    char                    *Temp = NULL;
    ACPI_PARSE_OBJECT_LIST  *NewTemp;
    ACPI_PARSE_OBJECT_LIST  *Current;
    ACPI_PARSE_OBJECT_LIST  *Previous;
    BOOLEAN                 FoundTemp = FALSE;


    switch (Op->Common.AmlOpcode)
    {
    case AML_NAME_OP:

        Temp = (char *) (&Op->Named.Name);

        if (!strncmp(Temp, "_T_", 3))
        {
            /* Allocate and init a new Temp List node */

            NewTemp = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PARSE_OBJECT_LIST));
            if (!NewTemp)
            {
                return (AE_NO_MEMORY);
            }

            if (AcpiGbl_TempListHead)
            {
                Current = AcpiGbl_TempListHead;
                AcpiGbl_TempListHead = NewTemp;
                AcpiGbl_TempListHead->Op = Op;
                AcpiGbl_TempListHead->Next = Current;
            }
            else
            {
                AcpiGbl_TempListHead = NewTemp;
                AcpiGbl_TempListHead->Op = Op;
                AcpiGbl_TempListHead->Next = NULL;
            }
        }
        break;

    case AML_WHILE_OP:

        if (!AcpiDmIsSwitchBlock (Op, &Temp))
        {
            break;
        }

        /* Found a Switch */

        Op->Common.DisasmOpcode = ACPI_DASM_SWITCH;

        Previous = Current = AcpiGbl_TempListHead;
        while (Current)
        {
            /* Note, if we get here Temp is not NULL */

            if (!strncmp(Temp, (char *) (&Current->Op->Named.Name), 4))
            {
                /* Match found. Ignore disassembly */

                Current->Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;

                /* Remove from list */

                if (Current == AcpiGbl_TempListHead)
                {
                    AcpiGbl_TempListHead = Current->Next;
                }
                else
                {
                    Previous->Next = Current->Next;
                }

                Current->Op = NULL;
                Current->Next = NULL;
                ACPI_FREE (Current);
                FoundTemp = TRUE;
                break;
            }

            Previous = Current;
            Current = Current->Next;
        }

        if (!FoundTemp)
        {
            fprintf (stderr,
                "Warning: Declaration for temp name %.4s not found\n", Temp);
        }
        break;

    default:
        break;
    }

    return (AE_OK);
}


/*******************************************************************************
 *
 * FUNCTION:    AcpiDmClearTempList
 *
 * PARAMETERS:  None
 *
 * RETURN:      None
 *
 * DESCRIPTION: Removes any remaining temporary objects from global list and
 *              frees
 *
 ******************************************************************************/

void
AcpiDmClearTempList (
    void)
{
    ACPI_PARSE_OBJECT_LIST      *Current;


    while (AcpiGbl_TempListHead)
    {
        Current = AcpiGbl_TempListHead;
        AcpiGbl_TempListHead = AcpiGbl_TempListHead->Next;
        Current->Op = NULL;
        Current->Next = NULL;
        ACPI_FREE (Current);
    }
}


/*******************************************************************************
 *
 * FUNCTION:    AcpiDmIsSwitchBlock
 *
 * PARAMETERS:  Op              - While Object
 *              Temp            - Where the compiler temp name is returned
 *                                  (_T_x)
 *
 * 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
 *
 ******************************************************************************/

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;


    /* Check for One Op Predicate */

    OneOp = AcpiPsGetArg (Op, 0);
    if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP))
    {
        return (FALSE);
    }

    /* Check for Store Op */

    StoreOp = OneOp->Common.Next;
    if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP))
    {
        return (FALSE);
    }

    /* Check for Name Op with _T_ string */

    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);

    /* This is a Switch/Case control block */

    /* Ignore the One Op Predicate */

    OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;

    /* Ignore the Store Op, but not the children */

    StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;

    /*
     * 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.
     */
    PredicateOp = AcpiPsGetArg (StoreOp, 0);
    PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
    PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;

    /* Ignore the Name Op */

    NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;

    /* Remaining opcodes are the Case statements (If/ElseIf's) */

    CurrentOp = StoreOp->Common.Next;
    while (AcpiDmIsCaseBlock (CurrentOp))
    {
        /* Block is a Case structure */

        if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
        {
            /* ElseIf */

            CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
            CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        }

        /* If */

        CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;

        /*
         * 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.
         */
        TempOp = AcpiPsGetArg (CurrentOp, 0);
        switch (TempOp->Common.AmlOpcode)
        {
        case (AML_LOGICAL_EQUAL_OP):

            /* Ignore just the LEqual Op */

            TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;

            /* Ignore the NamePath Op */

            TempOp = AcpiPsGetArg (TempOp, 0);
            TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;

            /*
             * 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.
             */
            PredicateOp = TempOp->Common.Next;
            PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
            PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
            break;

        case (AML_LOGICAL_NOT_OP):

            /*
             * The Package will be the predicate of the Case statement.
             * It's under:
             *            LNOT
             *                LEQUAL
             *                    MATCH
             *                        PACKAGE
             */

            /* Get the LEqual Op from LNot */

            TempOp = AcpiPsGetArg (TempOp, 0);

            /* Get the Match Op from LEqual */

            TempOp = AcpiPsGetArg (TempOp, 0);

            /* Get the Package Op from Match */

            PredicateOp = AcpiPsGetArg (TempOp, 0);

            /* Mark as parameter list for paren closing */

            PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;

            /*
             * 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.
             */
            TempOp = AcpiPsGetArg (CurrentOp, 1);

            /*
             * Move the Package Op to the child (predicate) of the
             * Case statement.
             */
            CurrentOp->Common.Value.Arg = PredicateOp;
            PredicateOp->Common.Parent = CurrentOp;

            /* Add the block code */

            PredicateOp->Common.Next = TempOp;
            break;

        default:

            /* Should never get here */
            break;
        }

        /* Advance to next Case block */

        CurrentOp = CurrentOp->Common.Next;
    }

    /* If CurrentOp is now an Else, then this is a Default block */

    if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
    {
        CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT;
    }

    /*
     * 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.
     */
    CurrentOp = StoreOp->Common.Next->Common.Next;
    if (!CurrentOp)
    {
        return (FALSE);
    }
    if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
    {
        CurrentOp = CurrentOp->Common.Next;
        if (!CurrentOp)
        {
            return (FALSE);
        }
    }

    /* Ignore the Break Op */

    CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    return (TRUE);
}


/*******************************************************************************
 *
 * FUNCTION:    AcpiDmIsCaseBlock
 *
 * PARAMETERS:  Op              - Object to test
 *
 * RETURN:      TRUE if Object is beginning of a Case block.
 *
 * DESCRIPTION: Determines if an Object is the beginning of a Case block for a
 *              Switch/Case statement. Parse tree must be one of the following
 *              forms:
 *
 *              Else (Optional)
 *                  If
 *                      LEqual
 *                          -NamePath- _T_x
 *
 *              Else (Optional)
 *                  If
 *                      LNot
 *                          LEqual
 *                              Match
 *                                  Package
 *                                      ByteConst
 *                                      -NamePath- _T_x
 *
 ******************************************************************************/

static BOOLEAN
AcpiDmIsCaseBlock (
    ACPI_PARSE_OBJECT       *Op)
{
    ACPI_PARSE_OBJECT       *CurrentOp;


    if (!Op)
    {
        return (FALSE);
    }

    /* Look for an If or ElseIf */

    CurrentOp = Op;
    if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
    {
        CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        if (!CurrentOp)
        {
            return (FALSE);
        }
    }

    if (!CurrentOp || CurrentOp->Common.AmlOpcode != AML_IF_OP)
    {
        return (FALSE);
    }

    /* Child must be LEqual or LNot */

    CurrentOp = AcpiPsGetArg (CurrentOp, 0);
    if (!CurrentOp)
    {
        return (FALSE);
    }

    switch (CurrentOp->Common.AmlOpcode)
    {
    case (AML_LOGICAL_EQUAL_OP):

        /* Next child must be NamePath with string _T_ */

        CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        if (!CurrentOp || !CurrentOp->Common.Value.Name ||
            strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
        {
            return (FALSE);
        }
        break;

    case (AML_LOGICAL_NOT_OP):

        /* Child of LNot must be LEqual op */

        CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_LOGICAL_EQUAL_OP))
        {
            return (FALSE);
        }

        /* Child of LNot must be Match op */

        CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_MATCH_OP))
        {
            return (FALSE);
        }

        /* First child of Match must be Package op */

        CurrentOp = AcpiPsGetArg (CurrentOp, 0);
        if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_PACKAGE_OP))
        {
            return (FALSE);
        }

        /* Third child of Match must be NamePath with string _T_ */

        CurrentOp = AcpiPsGetArg (CurrentOp->Common.Parent, 2);
        if (!CurrentOp || !CurrentOp->Common.Value.Name ||
            strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
        {
            return (FALSE);
        }
        break;

    default:

        return (FALSE);
    }

    return (TRUE);
}
