FreeBSD/sys/contrib/dev/acpica/components/executer/exmisc.c
/*******************************************************************************
 *
 * FUNCTION:    AcpiExDoLogicalOp
 *
 * PARAMETERS:  Opcode              - AML opcode
 *              Operand0            - operand #0
 *              Operand1            - operand #1
 *              LogicalResult       - TRUE/FALSE result of the operation
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the
 *              functions here is to prevent a lot of pointer dereferencing
 *              to obtain the operands and to simplify the generation of the
 *              logical value. For the Numeric operators (LAnd and LOr), both
 *              operands must be integers. For the other logical operators,
 *              operands can be any combination of Integer/String/Buffer. The
 *              first operand determines the type to which the second operand
 *              will be converted.
 *
 *              Note: cleanest machine code seems to be produced by the code
 *              below, rather than using statements of the form:
 *                  Result = (Operand0 == Operand1);
 *
 ******************************************************************************/
AcpiExDoLogicalOp
PARAMETERS:  Opcode              - AML opcode
Operand0            - operand #0
Operand1            - operand #1
LogicalResult       - TRUE/FALSE result of the operation

Status

Execute a logical AML opcode. The purpose of having all of the
functions here is to prevent a lot of pointer dereferencing
to obtain the operands and to simplify the generation of the
logical value. For the Numeric operators (LAnd and LOr), both
operands must be integers. For the other logical operators,
operands can be any combination of Integer/String/Buffer. The
first operand determines the type to which the second operand
will be converted.

cleanest machine code seems to be produced by the code
below, rather than using statements of the form:
Result = (Operand0 == Operand1).
AcpiExDoLogicalOp PARAMETERS : Opcode - AML opcode Operand0 - operand #0 Operand1 - operand #1 LogicalResult - TRUE / FALSE result of the operation Status Execute a logical AML opcode . The purpose of having all of the functions here is to prevent a lot of pointer dereferencing to obtain the operands and to simplify the generation of the logical value . For the Numeric operators ( LAnd and LOr ) both operands must be integers . For the other logical operators operands can be any combination of Integer / String / Buffer . The first operand determines the type to which the second operand will be converted . cleanest machine code seems to be produced by the code below rather than using statements of the form : Result = ( Operand0 == Operand1 ) .
ACPI_STATUS
AcpiExDoLogicalOp (
    UINT16                  Opcode,
    ACPI_OPERAND_OBJECT     *Operand0,
    ACPI_OPERAND_OBJECT     *Operand1,
    BOOLEAN                 *LogicalResult)
{
    ACPI_OPERAND_OBJECT     *LocalOperand1 = Operand1;
    UINT64                  Integer0;
    UINT64                  Integer1;
    UINT32                  Length0;
    UINT32                  Length1;
    ACPI_STATUS             Status = AE_OK;
    BOOLEAN                 LocalResult = FALSE;
    int                     Compare;
    ACPI_FUNCTION_TRACE (ExDoLogicalOp);
    switch (Operand0->Common.Type)
    {
    case ACPI_TYPE_INTEGER:
        Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16);
        break;
    case ACPI_TYPE_STRING:
        Status = AcpiExConvertToString (
            Operand1, &LocalOperand1, ACPI_IMPLICIT_CONVERT_HEX);
        break;
    case ACPI_TYPE_BUFFER:
        Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1);
        break;
    default:
        Status = AE_AML_INTERNAL;
        break;
    }
    if (ACPI_FAILURE (Status))
    {
        goto Cleanup;
    }
    if (Operand0->Common.Type == ACPI_TYPE_INTEGER)
    {
        Integer0 = Operand0->Integer.Value;
        Integer1 = LocalOperand1->Integer.Value;
        switch (Opcode)
        {
        case AML_LEQUAL_OP:             
            if (Integer0 == Integer1)
            {
                LocalResult = TRUE;
            }
            break;
        case AML_LGREATER_OP:           
            if (Integer0 > Integer1)
            {
                LocalResult = TRUE;
            }
            break;
        case AML_LLESS_OP:              
            if (Integer0 < Integer1)
            {
                LocalResult = TRUE;
            }
            break;
        default:
            Status = AE_AML_INTERNAL;
            break;
        }
    }
    else
    {
        Length0 = Operand0->Buffer.Length;
        Length1 = LocalOperand1->Buffer.Length;
        Compare = memcmp (Operand0->Buffer.Pointer,
            LocalOperand1->Buffer.Pointer,
            (Length0 > Length1) ? Length1 : Length0);
        switch (Opcode)
        {
        case AML_LEQUAL_OP:             
            if ((Length0 == Length1) &&
                (Compare == 0))
            {
                LocalResult = TRUE;
            }
            break;
        case AML_LGREATER_OP:           
            if (Compare > 0)
            {
                LocalResult = TRUE;
                goto Cleanup;   
            }
            if (Compare < 0)
            {
                goto Cleanup;   
            }
            if (Length0 > Length1)
            {
                LocalResult = TRUE;
            }
            break;
        case AML_LLESS_OP:              
            if (Compare > 0)
            {
                goto Cleanup;   
            }
            if (Compare < 0)
            {
                LocalResult = TRUE;
                goto Cleanup;   
            }
            if (Length0 < Length1)
            {
                LocalResult = TRUE;
            }
            break;
        default:
            Status = AE_AML_INTERNAL;
            break;
        }
    }
Cleanup:
    if (LocalOperand1 != Operand1)
    {
        AcpiUtRemoveReference (LocalOperand1);
    }
    *LogicalResult = LocalResult;
    return_ACPI_STATUS (Status);
}
ACPI_STATUS AcpiExDoLogicalOp ( UINT16 Opcode , ACPI_OPERAND_OBJECT * Operand0 , ACPI_OPERAND_OBJECT * Operand1 , BOOLEAN * LogicalResult ) { ACPI_OPERAND_OBJECT * LocalOperand1 = Operand1 ; UINT64 Integer0 ; UINT64 Integer1 ; UINT32 Length0 ; UINT32 Length1 ; ACPI_STATUS Status = AE_OK ; BOOLEAN LocalResult = FALSE ; int Compare ; ACPI_FUNCTION_TRACE ( ExDoLogicalOp ) ; switch ( Operand0 -> Common . Type ) { case ACPI_TYPE_INTEGER : Status = AcpiExConvertToInteger ( Operand1 , & LocalOperand1 , 16 ) ; break ; case ACPI_TYPE_STRING : Status = AcpiExConvertToString ( Operand1 , & LocalOperand1 , ACPI_IMPLICIT_CONVERT_HEX ) ; break ; case ACPI_TYPE_BUFFER : Status = AcpiExConvertToBuffer ( Operand1 , & LocalOperand1 ) ; break ; default : Status = AE_AML_INTERNAL ; break ; } if ( ACPI_FAILURE ( Status ) ) { goto Cleanup ; } if ( Operand0 -> Common . Type == ACPI_TYPE_INTEGER ) { Integer0 = Operand0 -> Integer . Value ; Integer1 = LocalOperand1 -> Integer . Value ; switch ( Opcode ) { case AML_LEQUAL_OP : if ( Integer0 == Integer1 ) { LocalResult = TRUE ; } break ; case AML_LGREATER_OP : if ( Integer0 > Integer1 ) { LocalResult = TRUE ; } break ; case AML_LLESS_OP : if ( Integer0 < Integer1 ) { LocalResult = TRUE ; } break ; default : Status = AE_AML_INTERNAL ; break ; } } else { Length0 = Operand0 -> Buffer . Length ; Length1 = LocalOperand1 -> Buffer . Length ; Compare = memcmp ( Operand0 -> Buffer . Pointer , LocalOperand1 -> Buffer . Pointer , ( Length0 > Length1 ) ? Length1 : Length0 ) ; switch ( Opcode ) { case AML_LEQUAL_OP : if ( ( Length0 == Length1 ) && ( Compare == 0 ) ) { LocalResult = TRUE ; } break ; case AML_LGREATER_OP : if ( Compare > 0 ) { LocalResult = TRUE ; goto Cleanup ; } if ( Compare < 0 ) { goto Cleanup ; } if ( Length0 > Length1 ) { LocalResult = TRUE ; } break ; case AML_LLESS_OP : if ( Compare > 0 ) { goto Cleanup ; } if ( Compare < 0 ) { LocalResult = TRUE ; goto Cleanup ; } if ( Length0 < Length1 ) { LocalResult = TRUE ; } break ; default : Status = AE_AML_INTERNAL ; break ; } } Cleanup : if ( LocalOperand1 != Operand1 ) { AcpiUtRemoveReference ( LocalOperand1 ) ; } * LogicalResult = LocalResult ; return_ACPI_STATUS ( Status ) ; }
FUNCTION:    AcpiExDoLogicalOp
 PARAMETERS:  Opcode              - AML opcode
              Operand0            - operand #0
              Operand1            - operand #1
              LogicalResult       - TRUE/FALSE result of the operation
FUNCTION : AcpiExDoLogicalOp PARAMETERS : Opcode - AML opcode Operand0 - operand #0 Operand1 - operand #1 LogicalResult - TRUE / FALSE result of the operation
/*
     * Convert the second operand if necessary. The first operand
     * determines the type of the second operand, (See the Data Types
     * section of the ACPI 3.0+ specification.)  Both object types are
     * guaranteed to be either Integer/String/Buffer by the operand
     * resolution mechanism.
     */ /*
     * Two cases: 1) Both Integers, 2) Both Strings or Buffers
     */ /*
         * 1) Both operands are of type integer
         *    Note: LocalOperand1 may have changed above
         */ /* LEqual (Operand0, Operand1) */ /* LGreater (Operand0, Operand1) */ /* LLess (Operand0, Operand1) */ /*
         * 2) Both operands are Strings or both are Buffers
         *    Note: Code below takes advantage of common Buffer/String
         *          object fields. LocalOperand1 may have changed above. Use
         *          memcmp to handle nulls in buffers.
         */ /* Lexicographic compare: compare the data bytes */ /* LEqual (Operand0, Operand1) */ /* Length and all bytes must be equal */ /* Length and all bytes match ==> TRUE */ /* LGreater (Operand0, Operand1) */ /* TRUE */ /* FALSE */ /* Bytes match (to shortest length), compare lengths */ /* LLess (Operand0, Operand1) */ /* FALSE */ /* TRUE */ /* Bytes match (to shortest length), compare lengths */ /* New object was created if implicit conversion performed - delete */ /* Return the logical result and status */