lib/acpica/source/components/disassembler/dmopcode.c
/*******************************************************************************
 *
 * FUNCTION:    AcpiDmConvertToElseIf
 *
 * PARAMETERS:  OriginalElseOp          - ELSE Object to be examined
 *
 * RETURN:      None. Emits either an "Else" or an "ElseIf" ASL operator.
 *
 * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
 *
 * EXAMPLE:
 *
 * This If..Else..If nested sequence:
 *
 *        If (Arg0 == 1)
 *        {
 *            Local0 = 4
 *        }
 *        Else
 *        {
 *            If (Arg0 == 2)
 *            {
 *                Local0 = 5
 *            }
 *        }
 *
 * Is converted to this simpler If..ElseIf sequence:
 *
 *        If (Arg0 == 1)
 *        {
 *            Local0 = 4
 *        }
 *        ElseIf (Arg0 == 2)
 *        {
 *            Local0 = 5
 *        }
 *
 * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
 * macro that emits an Else opcode followed by an If opcode. This function
 * reverses these AML sequences back to an ElseIf macro where possible. This
 * can make the disassembled ASL code simpler and more like the original code.
 *
 ******************************************************************************/
AcpiDmConvertToElseIf
PARAMETERS:  OriginalElseOp          - ELSE Object to be examined

None. Emits either an "Else" or an "ElseIf" ASL operator.

Detect and convert an If..Else..If sequence to If..ElseIf



This If..Else..If nested sequence.







There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
macro that emits an Else opcode followed by an If opcode. This function
reverses these AML sequences back to an ElseIf macro where possible. This
can make the disassembled ASL code simpler and more like the original code.
AcpiDmConvertToElseIf PARAMETERS : OriginalElseOp - ELSE Object to be examined None . Emits either an " Else " or an " ElseIf " ASL operator . Detect and convert an If .. Else .. If sequence to If .. ElseIf This If .. Else .. If nested sequence . There is no actual ElseIf AML opcode . ElseIf is essentially an ASL macro that emits an Else opcode followed by an If opcode . This function reverses these AML sequences back to an ElseIf macro where possible . This can make the disassembled ASL code simpler and more like the original code .
static void
AcpiDmConvertToElseIf (
    ACPI_PARSE_OBJECT       *OriginalElseOp)
{
    ACPI_PARSE_OBJECT       *IfOp;
    ACPI_PARSE_OBJECT       *ElseOp;
    IfOp = OriginalElseOp->Common.Value.Arg;
    if (!IfOp ||
        (IfOp->Common.AmlOpcode != AML_IF_OP) ||
        (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
    {
        AcpiOsPrintf ("%s", "Else");
        return;
    }
    AcpiOsPrintf ("%s", "ElseIf");
    IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
    IfOp->Common.Parent = OriginalElseOp->Common.Parent;
    ElseOp = IfOp->Common.Next;
    if (ElseOp &&
        (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
    {
        ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
        ElseOp->Common.Next = OriginalElseOp->Common.Next;
    }
    else
    {
        IfOp->Common.Next = OriginalElseOp->Common.Next;
    }
    OriginalElseOp->Common.Value.Arg = NULL;
    OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
    OriginalElseOp->Common.Next = IfOp;
}
static void AcpiDmConvertToElseIf ( ACPI_PARSE_OBJECT * OriginalElseOp ) { ACPI_PARSE_OBJECT * IfOp ; ACPI_PARSE_OBJECT * ElseOp ; IfOp = OriginalElseOp -> Common . Value . Arg ; if ( ! IfOp || ( IfOp -> Common . AmlOpcode != AML_IF_OP ) || ( IfOp -> Asl . Next && ( IfOp -> Asl . Next -> Common . AmlOpcode != AML_ELSE_OP ) ) ) { AcpiOsPrintf ( " " , " " ) ; return ; } AcpiOsPrintf ( " " , " " ) ; IfOp -> Common . DisasmFlags |= ACPI_PARSEOP_ELSEIF ; IfOp -> Common . Parent = OriginalElseOp -> Common . Parent ; ElseOp = IfOp -> Common . Next ; if ( ElseOp && ( ElseOp -> Common . AmlOpcode == AML_ELSE_OP ) ) { ElseOp -> Common . Parent = OriginalElseOp -> Common . Parent ; ElseOp -> Common . Next = OriginalElseOp -> Common . Next ; } else { IfOp -> Common . Next = OriginalElseOp -> Common . Next ; } OriginalElseOp -> Common . Value . Arg = NULL ; OriginalElseOp -> Common . DisasmFlags |= ACPI_PARSEOP_IGNORE ; OriginalElseOp -> Common . DisasmOpcode = ACPI_DASM_LNOT_PREFIX ; OriginalElseOp -> Common . Next = IfOp ; }
FUNCTION:    AcpiDmConvertToElseIf
 PARAMETERS:  OriginalElseOp          - ELSE Object to be examined
FUNCTION : AcpiDmConvertToElseIf PARAMETERS : OriginalElseOp - ELSE Object to be examined
/*
     * To be able to perform the conversion, two conditions must be satisfied:
     * 1) The first child of the Else must be an If statement.
     * 2) The If block can only be followed by an Else block and these must
     *    be the only blocks under the original Else.
     */ /* Not an Else..If sequence, cannot convert to ElseIf */ /* Emit ElseIf, mark the IF as now an ELSEIF */ /* The IF parent will now be the same as the original ELSE parent */ /*
     * Update the NEXT pointers to restructure the parse tree, essentially
     * promoting an If..Else block up to the same level as the original
     * Else.
     *
     * Check if the IF has a corresponding ELSE peer
     */ /* If an ELSE matches the IF, promote it also */ /* Otherwise, set the IF NEXT to the original ELSE NEXT */ /* Detach the child IF block from the original ELSE */ /* Ignore the original ELSE from now on */ /* Insert IF (now ELSEIF) as next peer of the original ELSE */