--- /dev/null	ven. janv. 17 07:29:34 2014
+++ new/usr/src/common/acpica/compiler/aslfold.c	ven. janv. 17 07:29:34 2014
@@ -0,0 +1,569 @@
+/******************************************************************************
+ *
+ * Module Name: aslfold - Constant folding
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2014, 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 MERCHANTIBILITY 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 "aslcompiler.h"
+#include "aslcompiler.y.h"
+#include "amlcode.h"
+
+#include "acdispat.h"
+#include "acparser.h"
+
+#define _COMPONENT          ACPI_COMPILER
+        ACPI_MODULE_NAME    ("aslfold")
+
+/* Local prototypes */
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk1 (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context);
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk2 (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context);
+
+static ACPI_STATUS
+OpcAmlCheckForConstant (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context);
+
+static void
+OpcUpdateIntegerNode (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT64                  Value);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    OpcAmlEvaluationWalk1
+ *
+ * PARAMETERS:  ASL_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Descending callback for AML execution of constant subtrees
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk1 (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context)
+{
+    ACPI_WALK_STATE         *WalkState = Context;
+    ACPI_STATUS             Status;
+    ACPI_PARSE_OBJECT       *OutOp;
+
+
+    WalkState->Op = Op;
+    WalkState->Opcode = Op->Common.AmlOpcode;
+    WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+    /* Copy child pointer to Arg for compatibility with Interpreter */
+
+    if (Op->Asl.Child)
+    {
+        Op->Common.Value.Arg = Op->Asl.Child;
+    }
+
+    /* Call AML dispatcher */
+
+    Status = AcpiDsExecBeginOp (WalkState, &OutOp);
+    if (ACPI_FAILURE (Status))
+    {
+        AcpiOsPrintf ("Constant interpretation failed - %s\n",
+                        AcpiFormatException (Status));
+    }
+
+    return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    OpcAmlEvaluationWalk2
+ *
+ * PARAMETERS:  ASL_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Ascending callback for AML execution of constant subtrees
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OpcAmlEvaluationWalk2 (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context)
+{
+    ACPI_WALK_STATE         *WalkState = Context;
+    ACPI_STATUS             Status;
+
+
+    WalkState->Op = Op;
+    WalkState->Opcode = Op->Common.AmlOpcode;
+    WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+    /* Copy child pointer to Arg for compatibility with Interpreter */
+
+    if (Op->Asl.Child)
+    {
+        Op->Common.Value.Arg = Op->Asl.Child;
+    }
+
+    /* Call AML dispatcher */
+
+    Status = AcpiDsExecEndOp (WalkState);
+    if (ACPI_FAILURE (Status))
+    {
+        AcpiOsPrintf ("Constant interpretation failed - %s\n",
+                        AcpiFormatException (Status));
+    }
+
+    return (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    OpcAmlCheckForConstant
+ *
+ * PARAMETERS:  ASL_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Check one Op for a type 3/4/5 AML opcode
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+OpcAmlCheckForConstant (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context)
+{
+    ACPI_WALK_STATE         *WalkState = Context;
+
+
+    WalkState->Op = Op;
+    WalkState->Opcode = Op->Common.AmlOpcode;
+    WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
+
+    DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ",
+                Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName);
+
+    /*
+     * These opcodes do not appear in the OpcodeInfo table, but
+     * they represent constants, so abort the constant walk now.
+     */
+    if ((WalkState->Opcode == AML_RAW_DATA_BYTE) ||
+        (WalkState->Opcode == AML_RAW_DATA_WORD) ||
+        (WalkState->Opcode == AML_RAW_DATA_DWORD) ||
+        (WalkState->Opcode == AML_RAW_DATA_QWORD))
+    {
+        WalkState->WalkType = ACPI_WALK_CONST_OPTIONAL;
+        return (AE_TYPE);
+    }
+
+    if (!(WalkState->OpInfo->Flags & AML_CONSTANT))
+    {
+        /* The opcode is not a Type 3/4/5 opcode */
+
+        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+        {
+            DbgPrint (ASL_PARSE_OUTPUT,
+                "**** Valid Target, cannot reduce ****\n");
+        }
+        else
+        {
+            DbgPrint (ASL_PARSE_OUTPUT,
+                "**** Not a Type 3/4/5 opcode ****\n");
+        }
+
+        if (WalkState->WalkType == ACPI_WALK_CONST_OPTIONAL)
+        {
+            /*
+             * We are looking at at normal expression to see if it can be
+             * reduced. It can't. No error
+             */
+            return (AE_TYPE);
+        }
+
+        /*
+         * This is an expression that MUST reduce to a constant, and it
+         * can't be reduced. This is an error
+         */
+        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+        {
+            AslError (ASL_ERROR, ASL_MSG_INVALID_TARGET, Op,
+                Op->Asl.ParseOpName);
+        }
+        else
+        {
+            AslError (ASL_ERROR, ASL_MSG_INVALID_CONSTANT_OP, Op,
+                Op->Asl.ParseOpName);
+        }
+
+        return (AE_TYPE);
+    }
+
+    /* Debug output */
+
+    DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345");
+
+    if (Op->Asl.CompileFlags & NODE_IS_TARGET)
+    {
+        DbgPrint (ASL_PARSE_OUTPUT, " TARGET");
+    }
+    if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG)
+    {
+        DbgPrint (ASL_PARSE_OUTPUT, " TERMARG");
+    }
+
+    DbgPrint (ASL_PARSE_OUTPUT, "\n");
+    return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    OpcAmlConstantWalk
+ *
+ * PARAMETERS:  ASL_WALK_CALLBACK
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Reduce an Op and its subtree to a constant if possible
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+OpcAmlConstantWalk (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT32                  Level,
+    void                    *Context)
+{
+    ACPI_WALK_STATE         *WalkState;
+    ACPI_STATUS             Status = AE_OK;
+    ACPI_OPERAND_OBJECT     *ObjDesc;
+    ACPI_PARSE_OBJECT       *RootOp;
+    ACPI_PARSE_OBJECT       *OriginalParentOp;
+    UINT8                   WalkType;
+
+
+    /*
+     * Only interested in subtrees that could possibly contain
+     * expressions that can be evaluated at this time
+     */
+    if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) ||
+          (Op->Asl.CompileFlags & NODE_IS_TARGET))
+    {
+        return (AE_OK);
+    }
+
+    /* Set the walk type based on the reduction used for this op */
+
+    if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG)
+    {
+        /* Op is a TermArg, constant folding is merely optional */
+
+        if (!Gbl_FoldConstants)
+        {
+            return (AE_CTRL_DEPTH);
+        }
+
+        WalkType = ACPI_WALK_CONST_OPTIONAL;
+    }
+    else
+    {
+        /* Op is a DataObject, the expression MUST reduced to a constant */
+
+        WalkType = ACPI_WALK_CONST_REQUIRED;
+    }
+
+    /* Create a new walk state */
+
+    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
+    if (!WalkState)
+    {
+        return (AE_NO_MEMORY);
+    }
+
+    WalkState->NextOp = NULL;
+    WalkState->Params = NULL;
+    WalkState->WalkType = WalkType;
+    WalkState->CallerReturnDesc = &ObjDesc;
+
+    /*
+     * Examine the entire subtree -- all nodes must be constants
+     * or type 3/4/5 opcodes
+     */
+    Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD,
+        OpcAmlCheckForConstant, NULL, WalkState);
+
+    /*
+     * Did we find an entire subtree that contains all constants and type 3/4/5
+     * opcodes?  (Only AE_OK or AE_TYPE returned from above)
+     */
+    if (Status == AE_TYPE)
+    {
+        /* Subtree cannot be reduced to a constant */
+
+        if (WalkState->WalkType == ACPI_WALK_CONST_OPTIONAL)
+        {
+            AcpiDsDeleteWalkState (WalkState);
+            return (AE_OK);
+        }
+
+        /* Don't descend any further, and use a default "constant" value */
+
+        Status = AE_CTRL_DEPTH;
+    }
+    else
+    {
+        /* Subtree can be reduced */
+
+        /* Allocate a new temporary root for this subtree */
+
+        RootOp = TrAllocateNode (PARSEOP_INTEGER);
+        if (!RootOp)
+        {
+            return (AE_NO_MEMORY);
+        }
+
+        RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
+
+        OriginalParentOp = Op->Common.Parent;
+        Op->Common.Parent = RootOp;
+
+        /* Hand off the subtree to the AML interpreter */
+
+        Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
+            OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
+        Op->Common.Parent = OriginalParentOp;
+
+        /* TBD: we really *should* release the RootOp node */
+
+        if (ACPI_SUCCESS (Status))
+        {
+            TotalFolds++;
+
+            /* Get the final result */
+
+            Status = AcpiDsResultPop (&ObjDesc, WalkState);
+        }
+
+        /* Check for error from the ACPICA core */
+
+        if (ACPI_FAILURE (Status))
+        {
+            AslCoreSubsystemError (Op, Status,
+                "Failure during constant evaluation", FALSE);
+        }
+    }
+
+    if (ACPI_FAILURE (Status))
+    {
+        /* We could not resolve the subtree for some reason */
+
+        AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op,
+            Op->Asl.ParseOpName);
+
+        /* Set the subtree value to ZERO anyway. Eliminates further errors */
+
+        OpcUpdateIntegerNode (Op, 0);
+    }
+    else
+    {
+        AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op,
+            Op->Asl.ParseOpName);
+
+        /*
+         * Because we know we executed type 3/4/5 opcodes above, we know that
+         * the result must be either an Integer, String, or Buffer.
+         */
+        switch (ObjDesc->Common.Type)
+        {
+        case ACPI_TYPE_INTEGER:
+
+            OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value);
+
+            DbgPrint (ASL_PARSE_OUTPUT,
+                "Constant expression reduced to (%s) %8.8X%8.8X\n",
+                Op->Asl.ParseOpName,
+                ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
+            break;
+
+        case ACPI_TYPE_STRING:
+
+            Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
+            Op->Common.AmlOpcode = AML_STRING_OP;
+            Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1;
+            Op->Common.Value.String = ObjDesc->String.Pointer;
+
+            DbgPrint (ASL_PARSE_OUTPUT,
+                "Constant expression reduced to (STRING) %s\n",
+                Op->Common.Value.String);
+
+            break;
+
+        case ACPI_TYPE_BUFFER:
+
+            Op->Asl.ParseOpcode = PARSEOP_BUFFER;
+            Op->Common.AmlOpcode = AML_BUFFER_OP;
+            Op->Asl.CompileFlags = NODE_AML_PACKAGE;
+            UtSetParseOpName (Op);
+
+            /* Child node is the buffer length */
+
+            RootOp = TrAllocateNode (PARSEOP_INTEGER);
+
+            RootOp->Asl.AmlOpcode = AML_DWORD_OP;
+            RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
+            RootOp->Asl.Parent = Op;
+
+            (void) OpcSetOptimalIntegerSize (RootOp);
+
+            Op->Asl.Child = RootOp;
+            Op = RootOp;
+            UtSetParseOpName (Op);
+
+            /* Peer to the child is the raw buffer data */
+
+            RootOp = TrAllocateNode (PARSEOP_RAW_DATA);
+            RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
+            RootOp->Asl.AmlLength = ObjDesc->Buffer.Length;
+            RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
+            RootOp->Asl.Parent = Op->Asl.Parent;
+
+            Op->Asl.Next = RootOp;
+            Op = RootOp;
+
+            DbgPrint (ASL_PARSE_OUTPUT,
+                "Constant expression reduced to (BUFFER) length %X\n",
+                ObjDesc->Buffer.Length);
+            break;
+
+        default:
+
+            printf ("Unsupported return type: %s\n",
+                AcpiUtGetObjectTypeName (ObjDesc));
+            break;
+        }
+    }
+
+    UtSetParseOpName (Op);
+    Op->Asl.Child = NULL;
+
+    AcpiDsDeleteWalkState (WalkState);
+    return (AE_CTRL_DEPTH);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    OpcUpdateIntegerNode
+ *
+ * PARAMETERS:  Op                  - Current parse object
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Update node to the correct integer type.
+ *
+ ******************************************************************************/
+
+static void
+OpcUpdateIntegerNode (
+    ACPI_PARSE_OBJECT       *Op,
+    UINT64                  Value)
+{
+
+    Op->Common.Value.Integer = Value;
+
+    /*
+     * The AmlLength is used by the parser to indicate a constant,
+     * (if non-zero). Length is either (1/2/4/8)
+     */
+    switch (Op->Asl.AmlLength)
+    {
+    case 1:
+
+        TrUpdateNode (PARSEOP_BYTECONST, Op);
+        Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
+        break;
+
+    case 2:
+
+        TrUpdateNode (PARSEOP_WORDCONST, Op);
+        Op->Asl.AmlOpcode = AML_RAW_DATA_WORD;
+        break;
+
+    case 4:
+
+        TrUpdateNode (PARSEOP_DWORDCONST, Op);
+        Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD;
+        break;
+
+    case 8:
+
+        TrUpdateNode (PARSEOP_QWORDCONST, Op);
+        Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD;
+        break;
+
+    case 0:
+    default:
+
+        OpcSetOptimalIntegerSize (Op);
+        TrUpdateNode (PARSEOP_INTEGER, Op);
+        break;
+    }
+
+    Op->Asl.AmlLength = 0;
+}
