xref: /freebsd/sys/contrib/dev/acpica/compiler/aslopt.c (revision 493deb390baef09f40125589cbdb714cb274ab04)
153289f6aSNate Lawson /******************************************************************************
253289f6aSNate Lawson  *
353289f6aSNate Lawson  * Module Name: aslopt- Compiler optimizations
453289f6aSNate Lawson  *
553289f6aSNate Lawson  *****************************************************************************/
653289f6aSNate Lawson 
7d244b227SJung-uk Kim /*
8f8146b88SJung-uk Kim  * Copyright (C) 2000 - 2016, Intel Corp.
953289f6aSNate Lawson  * All rights reserved.
1053289f6aSNate Lawson  *
11d244b227SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12d244b227SJung-uk Kim  * modification, are permitted provided that the following conditions
13d244b227SJung-uk Kim  * are met:
14d244b227SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15d244b227SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16d244b227SJung-uk Kim  *    without modification.
17d244b227SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18d244b227SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19d244b227SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20d244b227SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21d244b227SJung-uk Kim  *    binary redistribution.
22d244b227SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23d244b227SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24d244b227SJung-uk Kim  *    from this software without specific prior written permission.
2553289f6aSNate Lawson  *
26d244b227SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27d244b227SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28d244b227SJung-uk Kim  * Software Foundation.
2953289f6aSNate Lawson  *
30d244b227SJung-uk Kim  * NO WARRANTY
31d244b227SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32d244b227SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33d244b227SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34d244b227SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35d244b227SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36d244b227SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37d244b227SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38d244b227SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39d244b227SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40d244b227SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41d244b227SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42d244b227SJung-uk Kim  */
4353289f6aSNate Lawson 
44ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
4553289f6aSNate Lawson #include "aslcompiler.y.h"
4653289f6aSNate Lawson 
47ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
48ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
49ab6f3bf9SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
5053289f6aSNate Lawson 
5153289f6aSNate Lawson 
5253289f6aSNate Lawson #define _COMPONENT          ACPI_COMPILER
5353289f6aSNate Lawson         ACPI_MODULE_NAME    ("aslopt")
5453289f6aSNate Lawson 
5553289f6aSNate Lawson 
56fba7fc7eSJung-uk Kim static UINT32               OptTotal = 0;
57fba7fc7eSJung-uk Kim 
58fba7fc7eSJung-uk Kim /* Local prototypes */
59fba7fc7eSJung-uk Kim 
60fba7fc7eSJung-uk Kim static ACPI_STATUS
61fba7fc7eSJung-uk Kim OptSearchToRoot (
62fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
63fba7fc7eSJung-uk Kim     ACPI_WALK_STATE         *WalkState,
64fba7fc7eSJung-uk Kim     ACPI_NAMESPACE_NODE     *CurrentNode,
65fba7fc7eSJung-uk Kim     ACPI_NAMESPACE_NODE     *TargetNode,
66fba7fc7eSJung-uk Kim     ACPI_BUFFER             *TargetPath,
67fba7fc7eSJung-uk Kim     char                    **NewPath);
68fba7fc7eSJung-uk Kim 
69fba7fc7eSJung-uk Kim static ACPI_STATUS
70fba7fc7eSJung-uk Kim OptBuildShortestPath (
71fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
72fba7fc7eSJung-uk Kim     ACPI_WALK_STATE         *WalkState,
73fba7fc7eSJung-uk Kim     ACPI_NAMESPACE_NODE     *CurrentNode,
74fba7fc7eSJung-uk Kim     ACPI_NAMESPACE_NODE     *TargetNode,
75fba7fc7eSJung-uk Kim     ACPI_BUFFER             *CurrentPath,
76fba7fc7eSJung-uk Kim     ACPI_BUFFER             *TargetPath,
77fba7fc7eSJung-uk Kim     ACPI_SIZE               AmlNameStringLength,
78fba7fc7eSJung-uk Kim     UINT8                   IsDeclaration,
79fba7fc7eSJung-uk Kim     char                    **ReturnNewPath);
80fba7fc7eSJung-uk Kim 
81fba7fc7eSJung-uk Kim static ACPI_STATUS
82fba7fc7eSJung-uk Kim OptOptimizeNameDeclaration (
83fba7fc7eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
84fba7fc7eSJung-uk Kim     ACPI_WALK_STATE         *WalkState,
85fba7fc7eSJung-uk Kim     ACPI_NAMESPACE_NODE     *CurrentNode,
86fba7fc7eSJung-uk Kim     ACPI_NAMESPACE_NODE     *TargetNode,
87fba7fc7eSJung-uk Kim     char                    *AmlNameString,
88fba7fc7eSJung-uk Kim     char                    **NewPath);
8953289f6aSNate Lawson 
9053289f6aSNate Lawson 
9153289f6aSNate Lawson /*******************************************************************************
9253289f6aSNate Lawson  *
9353289f6aSNate Lawson  * FUNCTION:    OptSearchToRoot
9453289f6aSNate Lawson  *
9553289f6aSNate Lawson  * PARAMETERS:  Op                  - Current parser op
9653289f6aSNate Lawson  *              WalkState           - Current state
9753289f6aSNate Lawson  *              CurrentNode         - Where we are in the namespace
9853289f6aSNate Lawson  *              TargetNode          - Node to which we are referring
9953289f6aSNate Lawson  *              TargetPath          - External full path to the target node
10053289f6aSNate Lawson  *              NewPath             - Where the optimized path is returned
10153289f6aSNate Lawson  *
10253289f6aSNate Lawson  * RETURN:      Status
10353289f6aSNate Lawson  *
10453289f6aSNate Lawson  * DESCRIPTION: Attempt to optimize a reference to a single 4-character ACPI
10553289f6aSNate Lawson  *              name utilizing the search-to-root name resolution algorithm
10653289f6aSNate Lawson  *              that is used by AML interpreters.
10753289f6aSNate Lawson  *
10853289f6aSNate Lawson  ******************************************************************************/
10953289f6aSNate Lawson 
110fba7fc7eSJung-uk Kim static ACPI_STATUS
11153289f6aSNate Lawson OptSearchToRoot (
11253289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
11353289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState,
11453289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *CurrentNode,
11553289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *TargetNode,
11653289f6aSNate Lawson     ACPI_BUFFER             *TargetPath,
11753289f6aSNate Lawson     char                    **NewPath)
11853289f6aSNate Lawson {
11953289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node;
12053289f6aSNate Lawson     ACPI_GENERIC_STATE      ScopeInfo;
12153289f6aSNate Lawson     ACPI_STATUS             Status;
12253289f6aSNate Lawson     char                    *Path;
12353289f6aSNate Lawson 
12453289f6aSNate Lawson 
1251a39cfb0SJung-uk Kim     ACPI_FUNCTION_NAME (OptSearchToRoot);
12653289f6aSNate Lawson 
12753289f6aSNate Lawson 
12853289f6aSNate Lawson     /*
12953289f6aSNate Lawson      * Check if search-to-root can be utilized. Use the last NameSeg of
13053289f6aSNate Lawson      * the NamePath and 1) See if can be found and 2) If found, make
13153289f6aSNate Lawson      * sure that it is the same node that we want. If there is another
13253289f6aSNate Lawson      * name in the search path before the one we want, the nodes will
13353289f6aSNate Lawson      * not match, and we cannot use this optimization.
13453289f6aSNate Lawson      */
135f8146b88SJung-uk Kim     Path = &(((char *) TargetPath->Pointer)[
136*493deb39SJung-uk Kim         TargetPath->Length - ACPI_NAME_SIZE]);
13753289f6aSNate Lawson     ScopeInfo.Scope.Node = CurrentNode;
13853289f6aSNate Lawson 
13953289f6aSNate Lawson     /* Lookup the NameSeg using SEARCH_PARENT (search-to-root) */
14053289f6aSNate Lawson 
14153289f6aSNate Lawson     Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
14253289f6aSNate Lawson         ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
14353289f6aSNate Lawson         WalkState, &(Node));
14453289f6aSNate Lawson     if (ACPI_FAILURE (Status))
14553289f6aSNate Lawson     {
14653289f6aSNate Lawson         return (Status);
14753289f6aSNate Lawson     }
14853289f6aSNate Lawson 
14953289f6aSNate Lawson     /*
15053289f6aSNate Lawson      * We found the name, but we must check to make sure that the node
15153289f6aSNate Lawson      * matches. Otherwise, there is another identical name in the search
15253289f6aSNate Lawson      * path that precludes the use of this optimization.
15353289f6aSNate Lawson      */
15453289f6aSNate Lawson     if (Node != TargetNode)
15553289f6aSNate Lawson     {
15653289f6aSNate Lawson         /*
15753289f6aSNate Lawson          * This means that another object with the same name was found first,
15853289f6aSNate Lawson          * and we cannot use this optimization.
15953289f6aSNate Lawson          */
16053289f6aSNate Lawson         return (AE_NOT_FOUND);
16153289f6aSNate Lawson     }
16253289f6aSNate Lawson 
16353289f6aSNate Lawson     /* Found the node, we can use this optimization */
16453289f6aSNate Lawson 
16553289f6aSNate Lawson     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
16653289f6aSNate Lawson         "NAMESEG:   %-24s", Path));
16753289f6aSNate Lawson 
16853289f6aSNate Lawson     /* We must allocate a new string for the name (TargetPath gets deleted) */
16953289f6aSNate Lawson 
170313a0c13SJung-uk Kim     *NewPath = UtStringCacheCalloc (ACPI_NAME_SIZE + 1);
1715ef50723SJung-uk Kim     strcpy (*NewPath, Path);
17253289f6aSNate Lawson 
1735ef50723SJung-uk Kim     if (strncmp (*NewPath, "_T_", 3))
174c8466860SMark Santcroos     {
175f8146b88SJung-uk Kim         AslError (ASL_OPTIMIZATION, ASL_MSG_SINGLE_NAME_OPTIMIZATION,
176f8146b88SJung-uk Kim             Op, *NewPath);
177c8466860SMark Santcroos     }
17853289f6aSNate Lawson 
17953289f6aSNate Lawson     return (AE_OK);
18053289f6aSNate Lawson }
18153289f6aSNate Lawson 
18253289f6aSNate Lawson 
18353289f6aSNate Lawson /*******************************************************************************
18453289f6aSNate Lawson  *
18553289f6aSNate Lawson  * FUNCTION:    OptBuildShortestPath
18653289f6aSNate Lawson  *
18753289f6aSNate Lawson  * PARAMETERS:  Op                  - Current parser op
18853289f6aSNate Lawson  *              WalkState           - Current state
18953289f6aSNate Lawson  *              CurrentNode         - Where we are in the namespace
19053289f6aSNate Lawson  *              TargetNode          - Node to which we are referring
19153289f6aSNate Lawson  *              CurrentPath         - External full path to the current node
19253289f6aSNate Lawson  *              TargetPath          - External full path to the target node
19353289f6aSNate Lawson  *              AmlNameStringLength - Length of the original namepath
19453289f6aSNate Lawson  *              IsDeclaration       - TRUE for declaration, FALSE for reference
19553289f6aSNate Lawson  *              ReturnNewPath       - Where the optimized path is returned
19653289f6aSNate Lawson  *
19753289f6aSNate Lawson  * RETURN:      Status
19853289f6aSNate Lawson  *
19953289f6aSNate Lawson  * DESCRIPTION: Build an optimal NamePath using carats
20053289f6aSNate Lawson  *
20153289f6aSNate Lawson  ******************************************************************************/
20253289f6aSNate Lawson 
203fba7fc7eSJung-uk Kim static ACPI_STATUS
20453289f6aSNate Lawson OptBuildShortestPath (
20553289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
20653289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState,
20753289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *CurrentNode,
20853289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *TargetNode,
20953289f6aSNate Lawson     ACPI_BUFFER             *CurrentPath,
21053289f6aSNate Lawson     ACPI_BUFFER             *TargetPath,
21153289f6aSNate Lawson     ACPI_SIZE               AmlNameStringLength,
21253289f6aSNate Lawson     UINT8                   IsDeclaration,
21353289f6aSNate Lawson     char                    **ReturnNewPath)
21453289f6aSNate Lawson {
21553289f6aSNate Lawson     UINT32                  NumCommonSegments;
21653289f6aSNate Lawson     UINT32                  MaxCommonSegments;
217a9f12690SJung-uk Kim     UINT32                  Index;
21853289f6aSNate Lawson     UINT32                  NumCarats;
219a9f12690SJung-uk Kim     UINT32                  i;
220f8146b88SJung-uk Kim     char                    *NewPathInternal;
22153289f6aSNate Lawson     char                    *NewPathExternal;
22253289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node;
22353289f6aSNate Lawson     ACPI_GENERIC_STATE      ScopeInfo;
22453289f6aSNate Lawson     ACPI_STATUS             Status;
22553289f6aSNate Lawson     BOOLEAN                 SubPath = FALSE;
22653289f6aSNate Lawson 
22753289f6aSNate Lawson 
2281a39cfb0SJung-uk Kim     ACPI_FUNCTION_NAME (OptBuildShortestPath);
22953289f6aSNate Lawson 
23053289f6aSNate Lawson 
23153289f6aSNate Lawson     ScopeInfo.Scope.Node = CurrentNode;
23253289f6aSNate Lawson 
23353289f6aSNate Lawson     /*
23453289f6aSNate Lawson      * Determine the maximum number of NameSegs that the Target and Current paths
23553289f6aSNate Lawson      * can possibly have in common. (To optimize, we have to have at least 1)
23653289f6aSNate Lawson      *
23753289f6aSNate Lawson      * Note: The external NamePath string lengths are always a multiple of 5
23853289f6aSNate Lawson      * (ACPI_NAME_SIZE + separator)
23953289f6aSNate Lawson      */
24053289f6aSNate Lawson     MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH;
24153289f6aSNate Lawson     if (CurrentPath->Length < TargetPath->Length)
24253289f6aSNate Lawson     {
24353289f6aSNate Lawson         MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH;
24453289f6aSNate Lawson     }
24553289f6aSNate Lawson 
24653289f6aSNate Lawson     /*
24753289f6aSNate Lawson      * Determine how many NameSegs the two paths have in common.
24853289f6aSNate Lawson      * (Starting from the root)
24953289f6aSNate Lawson      */
25053289f6aSNate Lawson     for (NumCommonSegments = 0;
25153289f6aSNate Lawson          NumCommonSegments < MaxCommonSegments;
25253289f6aSNate Lawson          NumCommonSegments++)
25353289f6aSNate Lawson     {
25453289f6aSNate Lawson         /* Compare two single NameSegs */
25553289f6aSNate Lawson 
256f8146b88SJung-uk Kim         Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1;
257f8146b88SJung-uk Kim 
2588ef1a331SJung-uk Kim         if (!ACPI_COMPARE_NAME (
259f8146b88SJung-uk Kim             &(ACPI_CAST_PTR (char, TargetPath->Pointer)) [Index],
260f8146b88SJung-uk Kim             &(ACPI_CAST_PTR (char, CurrentPath->Pointer)) [Index]))
26153289f6aSNate Lawson         {
26253289f6aSNate Lawson             /* Mismatch */
26353289f6aSNate Lawson 
26453289f6aSNate Lawson             break;
26553289f6aSNate Lawson         }
26653289f6aSNate Lawson     }
26753289f6aSNate Lawson 
268a88e22b7SJung-uk Kim     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %u",
269fba7fc7eSJung-uk Kim         NumCommonSegments));
27053289f6aSNate Lawson 
27153289f6aSNate Lawson     /* There must be at least 1 common NameSeg in order to optimize */
27253289f6aSNate Lawson 
27353289f6aSNate Lawson     if (NumCommonSegments == 0)
27453289f6aSNate Lawson     {
27553289f6aSNate Lawson         return (AE_NOT_FOUND);
27653289f6aSNate Lawson     }
27753289f6aSNate Lawson 
27853289f6aSNate Lawson     if (NumCommonSegments == MaxCommonSegments)
27953289f6aSNate Lawson     {
28053289f6aSNate Lawson         if (CurrentPath->Length == TargetPath->Length)
28153289f6aSNate Lawson         {
28253289f6aSNate Lawson             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH"));
28353289f6aSNate Lawson             return (AE_NOT_FOUND);
28453289f6aSNate Lawson         }
28553289f6aSNate Lawson         else
28653289f6aSNate Lawson         {
28753289f6aSNate Lawson             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH"));
28853289f6aSNate Lawson             SubPath = TRUE;
28953289f6aSNate Lawson         }
29053289f6aSNate Lawson     }
29153289f6aSNate Lawson 
29253289f6aSNate Lawson     /* Determine how many prefix Carats are required */
29353289f6aSNate Lawson 
294fba7fc7eSJung-uk Kim     NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) -
295fba7fc7eSJung-uk Kim         NumCommonSegments;
29653289f6aSNate Lawson 
29753289f6aSNate Lawson     /*
29853289f6aSNate Lawson      * Construct a new target string
29953289f6aSNate Lawson      */
300f8146b88SJung-uk Kim     NewPathExternal =
301f8146b88SJung-uk Kim         ACPI_ALLOCATE_ZEROED (TargetPath->Length + NumCarats + 1);
30253289f6aSNate Lawson 
30353289f6aSNate Lawson     /* Insert the Carats into the Target string */
30453289f6aSNate Lawson 
30553289f6aSNate Lawson     for (i = 0; i < NumCarats; i++)
30653289f6aSNate Lawson     {
307efcc2a30SJung-uk Kim         NewPathExternal[i] = AML_PARENT_PREFIX;
30853289f6aSNate Lawson     }
30953289f6aSNate Lawson 
310fba7fc7eSJung-uk Kim     /*
311fba7fc7eSJung-uk Kim      * Copy only the necessary (optimal) segments from the original
312fba7fc7eSJung-uk Kim      * target string
313fba7fc7eSJung-uk Kim      */
31453289f6aSNate Lawson     Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1;
31553289f6aSNate Lawson 
31653289f6aSNate Lawson     /* Special handling for exact subpath in a name declaration */
31753289f6aSNate Lawson 
318f8146b88SJung-uk Kim     if (IsDeclaration && SubPath &&
319f8146b88SJung-uk Kim         (CurrentPath->Length > TargetPath->Length))
32053289f6aSNate Lawson     {
32153289f6aSNate Lawson         /*
322fba7fc7eSJung-uk Kim          * The current path is longer than the target, and the target is a
323fba7fc7eSJung-uk Kim          * subpath of the current path. We must include one more NameSeg of
324fba7fc7eSJung-uk Kim          * the target path
32553289f6aSNate Lawson          */
32653289f6aSNate Lawson         Index -= ACPI_PATH_SEGMENT_LENGTH;
327c8466860SMark Santcroos 
328c8466860SMark Santcroos         /* Special handling for Scope() operator */
329c8466860SMark Santcroos 
330c8466860SMark Santcroos         if (Op->Asl.AmlOpcode == AML_SCOPE_OP)
331c8466860SMark Santcroos         {
332efcc2a30SJung-uk Kim             NewPathExternal[i] = AML_PARENT_PREFIX;
333c8466860SMark Santcroos             i++;
334c8466860SMark Santcroos             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "(EXTRA ^)"));
335c8466860SMark Santcroos         }
33653289f6aSNate Lawson     }
33753289f6aSNate Lawson 
338fba7fc7eSJung-uk Kim     /* Make sure we haven't gone off the end of the target path */
339fba7fc7eSJung-uk Kim 
340fba7fc7eSJung-uk Kim     if (Index > TargetPath->Length)
341fba7fc7eSJung-uk Kim     {
342fba7fc7eSJung-uk Kim         Index = TargetPath->Length;
343fba7fc7eSJung-uk Kim     }
344fba7fc7eSJung-uk Kim 
345f8146b88SJung-uk Kim     strcpy (&NewPathExternal[i],
346f8146b88SJung-uk Kim         &(ACPI_CAST_PTR (char, TargetPath->Pointer))[Index]);
34753289f6aSNate Lawson     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal));
34853289f6aSNate Lawson 
34953289f6aSNate Lawson     /*
350fba7fc7eSJung-uk Kim      * Internalize the new target string and check it against the original
351fba7fc7eSJung-uk Kim      * string to make sure that this is in fact an optimization. If the
352fba7fc7eSJung-uk Kim      * original string is already optimal, there is no point in continuing.
35353289f6aSNate Lawson      */
354f8146b88SJung-uk Kim     Status = AcpiNsInternalizeName (NewPathExternal, &NewPathInternal);
35553289f6aSNate Lawson     if (ACPI_FAILURE (Status))
35653289f6aSNate Lawson     {
357fba7fc7eSJung-uk Kim         AslCoreSubsystemError (Op, Status, "Internalizing new NamePath",
358fba7fc7eSJung-uk Kim             ASL_NO_ABORT);
359f8146b88SJung-uk Kim         goto Cleanup;
36053289f6aSNate Lawson     }
36153289f6aSNate Lawson 
362f8146b88SJung-uk Kim     if (strlen (NewPathInternal) >= AmlNameStringLength)
36353289f6aSNate Lawson     {
364fba7fc7eSJung-uk Kim         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
3651a39cfb0SJung-uk Kim             " NOT SHORTER (New %u old %u)",
366f8146b88SJung-uk Kim             (UINT32) strlen (NewPathInternal),
367f8146b88SJung-uk Kim             (UINT32) AmlNameStringLength));
368f8146b88SJung-uk Kim 
369f8146b88SJung-uk Kim         ACPI_FREE (NewPathInternal);
370f8146b88SJung-uk Kim         Status = AE_NOT_FOUND;
371f8146b88SJung-uk Kim         goto Cleanup;
37253289f6aSNate Lawson     }
37353289f6aSNate Lawson 
37453289f6aSNate Lawson     /*
37553289f6aSNate Lawson      * Check to make sure that the optimization finds the node we are
37653289f6aSNate Lawson      * looking for. This is simply a sanity check on the new
37753289f6aSNate Lawson      * path that has been created.
37853289f6aSNate Lawson      */
379f8146b88SJung-uk Kim     Status = AcpiNsLookup (&ScopeInfo, NewPathInternal,
38053289f6aSNate Lawson         ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
38153289f6aSNate Lawson         ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
38253289f6aSNate Lawson     if (ACPI_SUCCESS (Status))
38353289f6aSNate Lawson     {
38453289f6aSNate Lawson         /* Found the namepath, but make sure the node is correct */
38553289f6aSNate Lawson 
38653289f6aSNate Lawson         if (Node == TargetNode)
38753289f6aSNate Lawson         {
38853289f6aSNate Lawson             /* The lookup matched the node, accept this optimization */
38953289f6aSNate Lawson 
39053289f6aSNate Lawson             AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
39153289f6aSNate Lawson                 Op, NewPathExternal);
392f8146b88SJung-uk Kim             *ReturnNewPath = NewPathInternal;
39353289f6aSNate Lawson         }
39453289f6aSNate Lawson         else
39553289f6aSNate Lawson         {
39653289f6aSNate Lawson             /* Node is not correct, do not use this optimization */
39753289f6aSNate Lawson 
39853289f6aSNate Lawson             Status = AE_NOT_FOUND;
39953289f6aSNate Lawson             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE"));
40053289f6aSNate Lawson             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
40153289f6aSNate Lawson                 "Not using optimized name - found wrong node");
40253289f6aSNate Lawson         }
40353289f6aSNate Lawson     }
40453289f6aSNate Lawson     else
40553289f6aSNate Lawson     {
40653289f6aSNate Lawson         /* The lookup failed, we obviously cannot use this optimization */
40753289f6aSNate Lawson 
408f8146b88SJung-uk Kim         ACPI_FREE (NewPathInternal);
409f8146b88SJung-uk Kim 
41053289f6aSNate Lawson         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND"));
41153289f6aSNate Lawson         AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
41253289f6aSNate Lawson             "Not using optimized name - did not find node");
41353289f6aSNate Lawson     }
41453289f6aSNate Lawson 
415f8146b88SJung-uk Kim Cleanup:
416f8146b88SJung-uk Kim 
4171a39cfb0SJung-uk Kim     ACPI_FREE (NewPathExternal);
41853289f6aSNate Lawson     return (Status);
41953289f6aSNate Lawson }
42053289f6aSNate Lawson 
42153289f6aSNate Lawson 
42253289f6aSNate Lawson /*******************************************************************************
42353289f6aSNate Lawson  *
42453289f6aSNate Lawson  * FUNCTION:    OptOptimizeNameDeclaration
42553289f6aSNate Lawson  *
42653289f6aSNate Lawson  * PARAMETERS:  Op                  - Current parser op
42753289f6aSNate Lawson  *              WalkState           - Current state
42853289f6aSNate Lawson  *              CurrentNode         - Where we are in the namespace
42953289f6aSNate Lawson  *              AmlNameString       - Unoptimized namepath
43053289f6aSNate Lawson  *              NewPath             - Where the optimized path is returned
43153289f6aSNate Lawson  *
43253289f6aSNate Lawson  * RETURN:      Status. AE_OK If path is optimized
43353289f6aSNate Lawson  *
43453289f6aSNate Lawson  * DESCRIPTION: Perform a simple optimization of removing an extraneous
43553289f6aSNate Lawson  *              backslash prefix if we are already at the root scope.
43653289f6aSNate Lawson  *
43753289f6aSNate Lawson  ******************************************************************************/
43853289f6aSNate Lawson 
439fba7fc7eSJung-uk Kim static ACPI_STATUS
44053289f6aSNate Lawson OptOptimizeNameDeclaration (
44153289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
44253289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState,
44353289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *CurrentNode,
44453289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *TargetNode,
44553289f6aSNate Lawson     char                    *AmlNameString,
44653289f6aSNate Lawson     char                    **NewPath)
44753289f6aSNate Lawson {
44853289f6aSNate Lawson     ACPI_STATUS             Status;
44953289f6aSNate Lawson     char                    *NewPathExternal;
45053289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *Node;
45153289f6aSNate Lawson 
45253289f6aSNate Lawson 
4531a39cfb0SJung-uk Kim     ACPI_FUNCTION_TRACE (OptOptimizeNameDeclaration);
45453289f6aSNate Lawson 
45553289f6aSNate Lawson 
45653289f6aSNate Lawson     if (((CurrentNode == AcpiGbl_RootNode) ||
457f8146b88SJung-uk Kim         (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)) &&
458efcc2a30SJung-uk Kim             (ACPI_IS_ROOT_PREFIX (AmlNameString[0])))
45953289f6aSNate Lawson     {
46053289f6aSNate Lawson         /*
46153289f6aSNate Lawson          * The current scope is the root, and the namepath has a root prefix
46253289f6aSNate Lawson          * that is therefore extraneous. Remove it.
46353289f6aSNate Lawson          */
46453289f6aSNate Lawson         *NewPath = &AmlNameString[1];
46553289f6aSNate Lawson 
46653289f6aSNate Lawson         /* Debug output */
46753289f6aSNate Lawson 
46853289f6aSNate Lawson         Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath,
46953289f6aSNate Lawson             NULL, &NewPathExternal);
47053289f6aSNate Lawson         if (ACPI_FAILURE (Status))
47153289f6aSNate Lawson         {
472fba7fc7eSJung-uk Kim             AslCoreSubsystemError (Op, Status, "Externalizing NamePath",
473fba7fc7eSJung-uk Kim                 ASL_NO_ABORT);
47453289f6aSNate Lawson             return (Status);
47553289f6aSNate Lawson         }
47653289f6aSNate Lawson 
47753289f6aSNate Lawson         /*
47853289f6aSNate Lawson          * Check to make sure that the optimization finds the node we are
47953289f6aSNate Lawson          * looking for. This is simply a sanity check on the new
48053289f6aSNate Lawson          * path that has been created.
481042ff955SJung-uk Kim          *
482042ff955SJung-uk Kim          * We know that we are at the root, so NULL is used for the scope.
48353289f6aSNate Lawson          */
484042ff955SJung-uk Kim         Status = AcpiNsLookup (NULL, *NewPath,
48553289f6aSNate Lawson             ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
48653289f6aSNate Lawson             ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node));
48753289f6aSNate Lawson         if (ACPI_SUCCESS (Status))
48853289f6aSNate Lawson         {
48953289f6aSNate Lawson             /* Found the namepath, but make sure the node is correct */
49053289f6aSNate Lawson 
49153289f6aSNate Lawson             if (Node == TargetNode)
49253289f6aSNate Lawson             {
49353289f6aSNate Lawson                 /* The lookup matched the node, accept this optimization */
49453289f6aSNate Lawson 
49553289f6aSNate Lawson                 AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION,
49653289f6aSNate Lawson                     Op, NewPathExternal);
49753289f6aSNate Lawson 
49853289f6aSNate Lawson                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
49953289f6aSNate Lawson                     "AT ROOT:   %-24s", NewPathExternal));
50053289f6aSNate Lawson             }
50153289f6aSNate Lawson             else
50253289f6aSNate Lawson             {
50353289f6aSNate Lawson                 /* Node is not correct, do not use this optimization */
50453289f6aSNate Lawson 
50553289f6aSNate Lawson                 Status = AE_NOT_FOUND;
506fba7fc7eSJung-uk Kim                 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
507fba7fc7eSJung-uk Kim                     " ***** WRONG NODE"));
50853289f6aSNate Lawson                 AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
50953289f6aSNate Lawson                     "Not using optimized name - found wrong node");
51053289f6aSNate Lawson             }
51153289f6aSNate Lawson         }
51253289f6aSNate Lawson         else
51353289f6aSNate Lawson         {
51453289f6aSNate Lawson             /* The lookup failed, we obviously cannot use this optimization */
51553289f6aSNate Lawson 
516fba7fc7eSJung-uk Kim             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
517fba7fc7eSJung-uk Kim                 " ***** NOT FOUND"));
51853289f6aSNate Lawson             AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op,
51953289f6aSNate Lawson                 "Not using optimized name - did not find node");
52053289f6aSNate Lawson         }
52153289f6aSNate Lawson 
5221a39cfb0SJung-uk Kim         ACPI_FREE (NewPathExternal);
52353289f6aSNate Lawson         return (Status);
52453289f6aSNate Lawson     }
52553289f6aSNate Lawson 
52653289f6aSNate Lawson     /* Could not optimize */
52753289f6aSNate Lawson 
52853289f6aSNate Lawson     return (AE_NOT_FOUND);
52953289f6aSNate Lawson }
53053289f6aSNate Lawson 
53153289f6aSNate Lawson 
53253289f6aSNate Lawson /*******************************************************************************
53353289f6aSNate Lawson  *
53453289f6aSNate Lawson  * FUNCTION:    OptOptimizeNamePath
53553289f6aSNate Lawson  *
53653289f6aSNate Lawson  * PARAMETERS:  Op                  - Current parser op
53753289f6aSNate Lawson  *              Flags               - Opcode info flags
53853289f6aSNate Lawson  *              WalkState           - Current state
53953289f6aSNate Lawson  *              AmlNameString       - Unoptimized namepath
54053289f6aSNate Lawson  *              TargetNode          - Node to which AmlNameString refers
54153289f6aSNate Lawson  *
54253289f6aSNate Lawson  * RETURN:      None. If path is optimized, the Op is updated with new path
54353289f6aSNate Lawson  *
54453289f6aSNate Lawson  * DESCRIPTION: Optimize a Named Declaration or Reference to the minimal length.
54553289f6aSNate Lawson  *              Must take into account both the current location in the
54653289f6aSNate Lawson  *              namespace and the actual reference path.
54753289f6aSNate Lawson  *
54853289f6aSNate Lawson  ******************************************************************************/
54953289f6aSNate Lawson 
55053289f6aSNate Lawson void
55153289f6aSNate Lawson OptOptimizeNamePath (
55253289f6aSNate Lawson     ACPI_PARSE_OBJECT       *Op,
55353289f6aSNate Lawson     UINT32                  Flags,
55453289f6aSNate Lawson     ACPI_WALK_STATE         *WalkState,
55553289f6aSNate Lawson     char                    *AmlNameString,
55653289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *TargetNode)
55753289f6aSNate Lawson {
55853289f6aSNate Lawson     ACPI_STATUS             Status;
55953289f6aSNate Lawson     ACPI_BUFFER             TargetPath;
56053289f6aSNate Lawson     ACPI_BUFFER             CurrentPath;
56153289f6aSNate Lawson     ACPI_SIZE               AmlNameStringLength;
56253289f6aSNate Lawson     ACPI_NAMESPACE_NODE     *CurrentNode;
56353289f6aSNate Lawson     char                    *ExternalNameString;
56453289f6aSNate Lawson     char                    *NewPath = NULL;
56553289f6aSNate Lawson     ACPI_SIZE               HowMuchShorter;
56653289f6aSNate Lawson     ACPI_PARSE_OBJECT       *NextOp;
56753289f6aSNate Lawson 
56853289f6aSNate Lawson 
5691a39cfb0SJung-uk Kim     ACPI_FUNCTION_TRACE (OptOptimizeNamePath);
57053289f6aSNate Lawson 
57153289f6aSNate Lawson 
57253289f6aSNate Lawson     /* This is an optional optimization */
57353289f6aSNate Lawson 
57453289f6aSNate Lawson     if (!Gbl_ReferenceOptimizationFlag)
57553289f6aSNate Lawson     {
57653289f6aSNate Lawson         return_VOID;
57753289f6aSNate Lawson     }
57853289f6aSNate Lawson 
57953289f6aSNate Lawson     /* Various required items */
58053289f6aSNate Lawson 
581c8466860SMark Santcroos     if (!TargetNode || !WalkState || !AmlNameString || !Op->Common.Parent)
58253289f6aSNate Lawson     {
58353289f6aSNate Lawson         return_VOID;
58453289f6aSNate Lawson     }
58553289f6aSNate Lawson 
586313a0c13SJung-uk Kim     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
587313a0c13SJung-uk Kim         "PATH OPTIMIZE: Line %5d ParentOp [%12.12s] ThisOp [%12.12s] ",
58853289f6aSNate Lawson         Op->Asl.LogicalLineNumber,
58953289f6aSNate Lawson         AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode),
59053289f6aSNate Lawson         AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
59153289f6aSNate Lawson 
59253289f6aSNate Lawson     if (!(Flags & (AML_NAMED | AML_CREATE)))
59353289f6aSNate Lawson     {
59453289f6aSNate Lawson         if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)
59553289f6aSNate Lawson         {
59653289f6aSNate Lawson             /* We don't want to fuss with actual name declaration nodes here */
59753289f6aSNate Lawson 
59853289f6aSNate Lawson             ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
59953289f6aSNate Lawson                 "******* NAME DECLARATION\n"));
60053289f6aSNate Lawson             return_VOID;
60153289f6aSNate Lawson         }
60253289f6aSNate Lawson     }
60353289f6aSNate Lawson 
60453289f6aSNate Lawson     /*
60553289f6aSNate Lawson      * The original path must be longer than one NameSeg (4 chars) for there
60653289f6aSNate Lawson      * to be any possibility that it can be optimized to a shorter string
60753289f6aSNate Lawson      */
6085ef50723SJung-uk Kim     AmlNameStringLength = strlen (AmlNameString);
60953289f6aSNate Lawson     if (AmlNameStringLength <= ACPI_NAME_SIZE)
61053289f6aSNate Lawson     {
61153289f6aSNate Lawson         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
61253289f6aSNate Lawson             "NAMESEG %4.4s\n", AmlNameString));
61353289f6aSNate Lawson         return_VOID;
61453289f6aSNate Lawson     }
61553289f6aSNate Lawson 
61653289f6aSNate Lawson     /*
61753289f6aSNate Lawson      * We need to obtain the node that represents the current scope -- where
61853289f6aSNate Lawson      * we are right now in the namespace. We will compare this path
61953289f6aSNate Lawson      * against the Namepath, looking for commonality.
62053289f6aSNate Lawson      */
62153289f6aSNate Lawson     CurrentNode = AcpiGbl_RootNode;
62253289f6aSNate Lawson     if (WalkState->ScopeInfo)
62353289f6aSNate Lawson     {
62453289f6aSNate Lawson         CurrentNode = WalkState->ScopeInfo->Scope.Node;
62553289f6aSNate Lawson     }
62653289f6aSNate Lawson 
62753289f6aSNate Lawson     if (Flags & (AML_NAMED | AML_CREATE))
62853289f6aSNate Lawson     {
62953289f6aSNate Lawson         /* This is the declaration of a new name */
63053289f6aSNate Lawson 
631313a0c13SJung-uk Kim         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME\n"));
63253289f6aSNate Lawson 
633fba7fc7eSJung-uk Kim         /*
634042ff955SJung-uk Kim          * The node of interest is the parent of this node (the containing
635042ff955SJung-uk Kim          * scope). The actual namespace node may be up more than one level
636042ff955SJung-uk Kim          * of parse op or it may not exist at all (if we traverse back
637042ff955SJung-uk Kim          * up to the root.)
638fba7fc7eSJung-uk Kim          */
639042ff955SJung-uk Kim         NextOp = Op->Asl.Parent;
640042ff955SJung-uk Kim         while (NextOp && (!NextOp->Asl.Node))
641042ff955SJung-uk Kim         {
642042ff955SJung-uk Kim             NextOp = NextOp->Asl.Parent;
643042ff955SJung-uk Kim         }
644f8146b88SJung-uk Kim 
645042ff955SJung-uk Kim         if (NextOp && NextOp->Asl.Node)
646042ff955SJung-uk Kim         {
647042ff955SJung-uk Kim             CurrentNode = NextOp->Asl.Node;
648042ff955SJung-uk Kim         }
649042ff955SJung-uk Kim         else
65053289f6aSNate Lawson         {
65153289f6aSNate Lawson             CurrentNode = AcpiGbl_RootNode;
65253289f6aSNate Lawson         }
65353289f6aSNate Lawson     }
65453289f6aSNate Lawson     else
65553289f6aSNate Lawson     {
65653289f6aSNate Lawson         /* This is a reference to an existing named object */
65753289f6aSNate Lawson 
658313a0c13SJung-uk Kim         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REFERENCE\n"));
65953289f6aSNate Lawson     }
66053289f6aSNate Lawson 
66153289f6aSNate Lawson     /*
66253289f6aSNate Lawson      * Obtain the full paths to the two nodes that we are interested in
66353289f6aSNate Lawson      * (Target and current namespace location) in external
66453289f6aSNate Lawson      * format -- something we can easily manipulate
66553289f6aSNate Lawson      */
66653289f6aSNate Lawson     TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
667fe0f0bbbSJung-uk Kim     Status = AcpiNsHandleToPathname (TargetNode, &TargetPath, FALSE);
66853289f6aSNate Lawson     if (ACPI_FAILURE (Status))
66953289f6aSNate Lawson     {
670fba7fc7eSJung-uk Kim         AslCoreSubsystemError (Op, Status, "Getting Target NamePath",
671fba7fc7eSJung-uk Kim             ASL_NO_ABORT);
67253289f6aSNate Lawson         return_VOID;
67353289f6aSNate Lawson     }
674f8146b88SJung-uk Kim 
67553289f6aSNate Lawson     TargetPath.Length--;    /* Subtract one for null terminator */
67653289f6aSNate Lawson 
67753289f6aSNate Lawson     /* CurrentPath is the path to this scope (where we are in the namespace) */
67853289f6aSNate Lawson 
67953289f6aSNate Lawson     CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
680fe0f0bbbSJung-uk Kim     Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath, FALSE);
68153289f6aSNate Lawson     if (ACPI_FAILURE (Status))
68253289f6aSNate Lawson     {
683fba7fc7eSJung-uk Kim         AslCoreSubsystemError (Op, Status, "Getting Current NamePath",
684fba7fc7eSJung-uk Kim             ASL_NO_ABORT);
68553289f6aSNate Lawson         return_VOID;
68653289f6aSNate Lawson     }
687f8146b88SJung-uk Kim 
68853289f6aSNate Lawson     CurrentPath.Length--;   /* Subtract one for null terminator */
68953289f6aSNate Lawson 
69053289f6aSNate Lawson     /* Debug output only */
69153289f6aSNate Lawson 
69253289f6aSNate Lawson     Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString,
69353289f6aSNate Lawson         NULL, &ExternalNameString);
69453289f6aSNate Lawson     if (ACPI_FAILURE (Status))
69553289f6aSNate Lawson     {
696fba7fc7eSJung-uk Kim         AslCoreSubsystemError (Op, Status, "Externalizing NamePath",
697fba7fc7eSJung-uk Kim             ASL_NO_ABORT);
69853289f6aSNate Lawson         return_VOID;
69953289f6aSNate Lawson     }
70053289f6aSNate Lawson 
70153289f6aSNate Lawson     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
702313a0c13SJung-uk Kim         "CURRENT SCOPE: (%2u) %-37s FULL PATH TO NAME: (%2u) %-32s ACTUAL AML:%-32s\n",
703313a0c13SJung-uk Kim         (UINT32) CurrentPath.Length, (char *) CurrentPath.Pointer,
704313a0c13SJung-uk Kim         (UINT32) TargetPath.Length, (char *) TargetPath.Pointer,
705313a0c13SJung-uk Kim         ExternalNameString));
70653289f6aSNate Lawson 
7071a39cfb0SJung-uk Kim     ACPI_FREE (ExternalNameString);
70853289f6aSNate Lawson 
70953289f6aSNate Lawson     /*
71053289f6aSNate Lawson      * Attempt an optmization depending on the type of namepath
71153289f6aSNate Lawson      */
71253289f6aSNate Lawson     if (Flags & (AML_NAMED | AML_CREATE))
71353289f6aSNate Lawson     {
71453289f6aSNate Lawson         /*
71553289f6aSNate Lawson          * This is a named opcode and the namepath is a name declaration, not
71653289f6aSNate Lawson          * a reference.
71753289f6aSNate Lawson          */
71853289f6aSNate Lawson         Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode,
71953289f6aSNate Lawson             TargetNode, AmlNameString, &NewPath);
72053289f6aSNate Lawson         if (ACPI_FAILURE (Status))
72153289f6aSNate Lawson         {
72253289f6aSNate Lawson             /*
72353289f6aSNate Lawson              * 2) now attempt to
72453289f6aSNate Lawson              *    optimize the namestring with carats (up-arrow)
72553289f6aSNate Lawson              */
72653289f6aSNate Lawson             Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
72753289f6aSNate Lawson                 TargetNode, &CurrentPath, &TargetPath,
72853289f6aSNate Lawson                 AmlNameStringLength, 1, &NewPath);
72953289f6aSNate Lawson         }
73053289f6aSNate Lawson     }
73153289f6aSNate Lawson     else
73253289f6aSNate Lawson     {
73353289f6aSNate Lawson         /*
73453289f6aSNate Lawson          * This is a reference to an existing named object
73553289f6aSNate Lawson          *
73653289f6aSNate Lawson          * 1) Check if search-to-root can be utilized using the last
73753289f6aSNate Lawson          *    NameSeg of the NamePath
73853289f6aSNate Lawson          */
73953289f6aSNate Lawson         Status = OptSearchToRoot (Op, WalkState, CurrentNode,
74053289f6aSNate Lawson             TargetNode, &TargetPath, &NewPath);
74153289f6aSNate Lawson         if (ACPI_FAILURE (Status))
74253289f6aSNate Lawson         {
74353289f6aSNate Lawson             /*
74453289f6aSNate Lawson              * 2) Search-to-root could not be used, now attempt to
74553289f6aSNate Lawson              *    optimize the namestring with carats (up-arrow)
74653289f6aSNate Lawson              */
74753289f6aSNate Lawson             Status = OptBuildShortestPath (Op, WalkState, CurrentNode,
74853289f6aSNate Lawson                 TargetNode, &CurrentPath, &TargetPath,
74953289f6aSNate Lawson                 AmlNameStringLength, 0, &NewPath);
75053289f6aSNate Lawson         }
75153289f6aSNate Lawson     }
75253289f6aSNate Lawson 
75353289f6aSNate Lawson     /*
75453289f6aSNate Lawson      * Success from above indicates that the NamePath was successfully
75553289f6aSNate Lawson      * optimized. We need to update the parse op with the new name
75653289f6aSNate Lawson      */
75753289f6aSNate Lawson     if (ACPI_SUCCESS (Status))
75853289f6aSNate Lawson     {
7595ef50723SJung-uk Kim         HowMuchShorter = (AmlNameStringLength - strlen (NewPath));
76053289f6aSNate Lawson         OptTotal += HowMuchShorter;
76153289f6aSNate Lawson 
762313a0c13SJung-uk Kim         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS,
763313a0c13SJung-uk Kim             " REDUCED BY %2u (TOTAL SAVED %2u)",
764a9f12690SJung-uk Kim             (UINT32) HowMuchShorter, OptTotal));
76553289f6aSNate Lawson 
76653289f6aSNate Lawson         if (Flags & AML_NAMED)
76753289f6aSNate Lawson         {
76853289f6aSNate Lawson             if (Op->Asl.AmlOpcode == AML_ALIAS_OP)
76953289f6aSNate Lawson             {
77053289f6aSNate Lawson                 /*
77153289f6aSNate Lawson                  * ALIAS is the only oddball opcode, the name declaration
77253289f6aSNate Lawson                  * (alias name) is the second operand
77353289f6aSNate Lawson                  */
77453289f6aSNate Lawson                 Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath;
7755ef50723SJung-uk Kim                 Op->Asl.Child->Asl.Next->Asl.AmlLength = strlen (NewPath);
77653289f6aSNate Lawson             }
77753289f6aSNate Lawson             else
77853289f6aSNate Lawson             {
77953289f6aSNate Lawson                 Op->Asl.Child->Asl.Value.String = NewPath;
7805ef50723SJung-uk Kim                 Op->Asl.Child->Asl.AmlLength = strlen (NewPath);
78153289f6aSNate Lawson             }
78253289f6aSNate Lawson         }
78353289f6aSNate Lawson         else if (Flags & AML_CREATE)
78453289f6aSNate Lawson         {
78553289f6aSNate Lawson             /* Name must appear as the last parameter */
78653289f6aSNate Lawson 
78753289f6aSNate Lawson             NextOp = Op->Asl.Child;
78853289f6aSNate Lawson             while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION))
78953289f6aSNate Lawson             {
79053289f6aSNate Lawson                 NextOp = NextOp->Asl.Next;
79153289f6aSNate Lawson             }
79253289f6aSNate Lawson             /* Update the parse node with the new NamePath */
79353289f6aSNate Lawson 
79453289f6aSNate Lawson             NextOp->Asl.Value.String = NewPath;
7955ef50723SJung-uk Kim             NextOp->Asl.AmlLength = strlen (NewPath);
79653289f6aSNate Lawson         }
79753289f6aSNate Lawson         else
79853289f6aSNate Lawson         {
79953289f6aSNate Lawson             /* Update the parse node with the new NamePath */
80053289f6aSNate Lawson 
80153289f6aSNate Lawson             Op->Asl.Value.String = NewPath;
8025ef50723SJung-uk Kim             Op->Asl.AmlLength = strlen (NewPath);
80353289f6aSNate Lawson         }
80453289f6aSNate Lawson     }
80553289f6aSNate Lawson     else
80653289f6aSNate Lawson     {
80753289f6aSNate Lawson         ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL"));
80853289f6aSNate Lawson     }
80953289f6aSNate Lawson 
81053289f6aSNate Lawson     /* Cleanup path buffers */
81153289f6aSNate Lawson 
8121a39cfb0SJung-uk Kim     ACPI_FREE (TargetPath.Pointer);
8131a39cfb0SJung-uk Kim     ACPI_FREE (CurrentPath.Pointer);
81453289f6aSNate Lawson 
81553289f6aSNate Lawson     ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n"));
81653289f6aSNate Lawson     return_VOID;
81753289f6aSNate Lawson }
818