FreeBSD/sys/contrib/dev/acpica/compiler/asltree.c
/*******************************************************************************
 *
 * FUNCTION:    TrCreateAssignmentNode
 *
 * PARAMETERS:  Target              - Assignment target
 *              Source              - Assignment source
 *
 * RETURN:      Pointer to the new node. Aborts on allocation failure
 *
 * DESCRIPTION: Implements the C-style '=' operator. It changes the parse
 *              tree if possible to utilize the last argument of the math
 *              operators which is a target operand -- thus saving invocation
 *              of and additional Store() operator. An optimization.
 *
 ******************************************************************************/
TrCreateAssignmentNode
PARAMETERS:  Target              - Assignment target
Source              - Assignment source

Pointer to the new node. Aborts on allocation failure

Implements the C-style '=' operator. It changes the parse
tree if possible to utilize the last argument of the math
operators which is a target operand -- thus saving invocation
of and additional Store() operator. An optimization.
TrCreateAssignmentNode PARAMETERS : Target - Assignment target Source - Assignment source Pointer to the new node . Aborts on allocation failure Implements the C - style ' = ' operator . It changes the parse tree if possible to utilize the last argument of the math operators which is a target operand -- thus saving invocation of and additional Store () operator . An optimization .
ACPI_PARSE_OBJECT *
TrCreateAssignmentNode (
    ACPI_PARSE_OBJECT       *Target,
    ACPI_PARSE_OBJECT       *Source)
{
    ACPI_PARSE_OBJECT       *TargetOp;
    ACPI_PARSE_OBJECT       *SourceOp1;
    ACPI_PARSE_OBJECT       *SourceOp2;
    ACPI_PARSE_OBJECT       *Operator;
    DbgPrint (ASL_PARSE_OUTPUT,
        "\nTrCreateAssignmentNode  Line [%u to %u] Source %s Target %s\n",
        Source->Asl.LineNumber, Source->Asl.EndLine,
        UtGetOpName (Source->Asl.ParseOpcode),
        UtGetOpName (Target->Asl.ParseOpcode));
    TrSetNodeFlags (Target, NODE_IS_TARGET);
    switch (Source->Asl.ParseOpcode)
    {
    case PARSEOP_ADD:
    case PARSEOP_AND:
    case PARSEOP_DIVIDE:
    case PARSEOP_INDEX:
    case PARSEOP_MOD:
    case PARSEOP_MULTIPLY:
    case PARSEOP_NOT:
    case PARSEOP_OR:
    case PARSEOP_SHIFTLEFT:
    case PARSEOP_SHIFTRIGHT:
    case PARSEOP_SUBTRACT:
    case PARSEOP_XOR:
        break;
    default:
        goto CannotOptimize;
    }
    SourceOp1 = Source->Asl.Child;
    SourceOp2 = SourceOp1->Asl.Next;
    if (Source->Asl.ParseOpcode == PARSEOP_NOT)
    {
        SourceOp2 = SourceOp1;
    }
    if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE)
    {
        SourceOp2 = SourceOp2->Asl.Next;
    }
    TargetOp = SourceOp2->Asl.Next;
    if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO)
    {
        goto CannotOptimize;
    }
    SourceOp2->Asl.Next = Target;
    Target->Asl.Parent = Source;
    return (Source);
CannotOptimize:
    Operator = TrAllocateNode (PARSEOP_STORE);
    TrLinkChildren (Operator, 2, Source, Target);
    Operator->Asl.LineNumber        = Target->Asl.LineNumber;
    Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber;
    Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset;
    Operator->Asl.Column            = Target->Asl.Column;
    return (Operator);
}
ACPI_PARSE_OBJECT * TrCreateAssignmentNode ( ACPI_PARSE_OBJECT * Target , ACPI_PARSE_OBJECT * Source ) { ACPI_PARSE_OBJECT * TargetOp ; ACPI_PARSE_OBJECT * SourceOp1 ; ACPI_PARSE_OBJECT * SourceOp2 ; ACPI_PARSE_OBJECT * Operator ; DbgPrint ( ASL_PARSE_OUTPUT , " \n \n " , Source -> Asl . LineNumber , Source -> Asl . EndLine , UtGetOpName ( Source -> Asl . ParseOpcode ) , UtGetOpName ( Target -> Asl . ParseOpcode ) ) ; TrSetNodeFlags ( Target , NODE_IS_TARGET ) ; switch ( Source -> Asl . ParseOpcode ) { case PARSEOP_ADD : case PARSEOP_AND : case PARSEOP_DIVIDE : case PARSEOP_INDEX : case PARSEOP_MOD : case PARSEOP_MULTIPLY : case PARSEOP_NOT : case PARSEOP_OR : case PARSEOP_SHIFTLEFT : case PARSEOP_SHIFTRIGHT : case PARSEOP_SUBTRACT : case PARSEOP_XOR : break ; default : goto CannotOptimize ; } SourceOp1 = Source -> Asl . Child ; SourceOp2 = SourceOp1 -> Asl . Next ; if ( Source -> Asl . ParseOpcode == PARSEOP_NOT ) { SourceOp2 = SourceOp1 ; } if ( Source -> Asl . ParseOpcode == PARSEOP_DIVIDE ) { SourceOp2 = SourceOp2 -> Asl . Next ; } TargetOp = SourceOp2 -> Asl . Next ; if ( TargetOp -> Asl . ParseOpcode != PARSEOP_ZERO ) { goto CannotOptimize ; } SourceOp2 -> Asl . Next = Target ; Target -> Asl . Parent = Source ; return ( Source ) ; CannotOptimize : Operator = TrAllocateNode ( PARSEOP_STORE ) ; TrLinkChildren ( Operator , 2 , Source , Target ) ; Operator -> Asl . LineNumber = Target -> Asl . LineNumber ; Operator -> Asl . LogicalLineNumber = Target -> Asl . LogicalLineNumber ; Operator -> Asl . LogicalByteOffset = Target -> Asl . LogicalByteOffset ; Operator -> Asl . Column = Target -> Asl . Column ; return ( Operator ) ; }
FUNCTION:    TrCreateAssignmentNode
 PARAMETERS:  Target              - Assignment target
              Source              - Assignment source
FUNCTION : TrCreateAssignmentNode PARAMETERS : Target - Assignment target Source - Assignment source
/*
     * Only these operators can be optimized because they have
     * a target operand
     */ /* Otherwise, just create a normal Store operator */ /*
     * Transform the parse tree such that the target is moved to the
     * last operand of the operator
     */ /* NOT only has one operand, but has a target */ /* DIVIDE has an extra target operand (remainder) */ /*
     * Can't perform this optimization if there already is a target
     * for the operator (ZERO is a "no target" placeholder).
     */ /* Link in the target as the final operand */ /* Set the appropriate line numbers for the new node */