xref: /freebsd/sys/contrib/dev/acpica/compiler/asltransform.c (revision c66ec88fed842fbaad62c30d510644ceb7bd2d71)
1 /******************************************************************************
2  *
3  * Module Name: asltransform - Parse tree transforms
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include "aslcompiler.y.h"
154 #include <contrib/dev/acpica/include/acnamesp.h>
155 
156 #define _COMPONENT          ACPI_COMPILER
157         ACPI_MODULE_NAME    ("asltransform")
158 
159 /* Local prototypes */
160 
161 static void
162 TrTransformSubtree (
163     ACPI_PARSE_OBJECT       *Op);
164 
165 static char *
166 TrAmlGetNextTempName (
167     ACPI_PARSE_OBJECT       *Op,
168     UINT8                   *TempCount);
169 
170 static void
171 TrAmlInitLineNumbers (
172     ACPI_PARSE_OBJECT       *Op,
173     ACPI_PARSE_OBJECT       *Neighbor);
174 
175 static void
176 TrAmlInitNode (
177     ACPI_PARSE_OBJECT       *Op,
178     UINT16                  ParseOpcode);
179 
180 static void
181 TrAmlSetSubtreeParent (
182     ACPI_PARSE_OBJECT       *Op,
183     ACPI_PARSE_OBJECT       *Parent);
184 
185 static void
186 TrAmlInsertPeer (
187     ACPI_PARSE_OBJECT       *Op,
188     ACPI_PARSE_OBJECT       *NewPeer);
189 
190 static void
191 TrDoDefinitionBlock (
192     ACPI_PARSE_OBJECT       *Op);
193 
194 static void
195 TrDoSwitch (
196     ACPI_PARSE_OBJECT       *StartNode);
197 
198 static void
199 TrCheckForDuplicateCase (
200     ACPI_PARSE_OBJECT       *CaseOp,
201     ACPI_PARSE_OBJECT       *Predicate1);
202 
203 static BOOLEAN
204 TrCheckForBufferMatch (
205     ACPI_PARSE_OBJECT       *Next1,
206     ACPI_PARSE_OBJECT       *Next2);
207 
208 static void
209 TrDoMethod (
210     ACPI_PARSE_OBJECT       *Op);
211 
212 
213 /*******************************************************************************
214  *
215  * FUNCTION:    TrAmlGetNextTempName
216  *
217  * PARAMETERS:  Op              - Current parse op
218  *              TempCount       - Current temporary counter. Was originally
219  *                                per-module; Currently per method, could be
220  *                                expanded to per-scope.
221  *
222  * RETURN:      A pointer to name (allocated here).
223  *
224  * DESCRIPTION: Generate an ACPI name of the form _T_x. These names are
225  *              reserved for use by the ASL compiler. (_T_0 through _T_Z)
226  *
227  ******************************************************************************/
228 
229 static char *
230 TrAmlGetNextTempName (
231     ACPI_PARSE_OBJECT       *Op,
232     UINT8                   *TempCount)
233 {
234     char                    *TempName;
235 
236 
237     if (*TempCount >= (10 + 26))  /* 0-35 valid: 0-9 and A-Z for TempName[3] */
238     {
239         /* Too many temps */
240 
241         AslError (ASL_ERROR, ASL_MSG_TOO_MANY_TEMPS, Op, NULL);
242         return (NULL);
243     }
244 
245     TempName = UtLocalCalloc (5);
246 
247     if (*TempCount < 10)    /* 0-9 */
248     {
249         TempName[3] = (char) (*TempCount + '0');
250     }
251     else                    /* 10-35: A-Z */
252     {
253         TempName[3] = (char) (*TempCount + ('A' - 10));
254     }
255 
256     (*TempCount)++;
257 
258     /* First three characters are always "_T_" */
259 
260     TempName[0] = '_';
261     TempName[1] = 'T';
262     TempName[2] = '_';
263 
264     return (TempName);
265 }
266 
267 
268 /*******************************************************************************
269  *
270  * FUNCTION:    TrAmlInitLineNumbers
271  *
272  * PARAMETERS:  Op              - Op to be initialized
273  *              Neighbor        - Op used for initialization values
274  *
275  * RETURN:      None
276  *
277  * DESCRIPTION: Initialized the various line numbers for a parse node.
278  *
279  ******************************************************************************/
280 
281 static void
282 TrAmlInitLineNumbers (
283     ACPI_PARSE_OBJECT       *Op,
284     ACPI_PARSE_OBJECT       *Neighbor)
285 {
286 
287     Op->Asl.EndLine           = Neighbor->Asl.EndLine;
288     Op->Asl.EndLogicalLine    = Neighbor->Asl.EndLogicalLine;
289     Op->Asl.LineNumber        = Neighbor->Asl.LineNumber;
290     Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset;
291     Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber;
292 }
293 
294 
295 /*******************************************************************************
296  *
297  * FUNCTION:    TrAmlInitNode
298  *
299  * PARAMETERS:  Op              - Op to be initialized
300  *              ParseOpcode     - Opcode for this node
301  *
302  * RETURN:      None
303  *
304  * DESCRIPTION: Initialize a node with the parse opcode and opcode name.
305  *
306  ******************************************************************************/
307 
308 static void
309 TrAmlInitNode (
310     ACPI_PARSE_OBJECT       *Op,
311     UINT16                  ParseOpcode)
312 {
313 
314     Op->Asl.ParseOpcode = ParseOpcode;
315     UtSetParseOpName (Op);
316 }
317 
318 
319 /*******************************************************************************
320  *
321  * FUNCTION:    TrAmlSetSubtreeParent
322  *
323  * PARAMETERS:  Op              - First node in a list of peer nodes
324  *              Parent          - Parent of the subtree
325  *
326  * RETURN:      None
327  *
328  * DESCRIPTION: Set the parent for all peer nodes in a subtree
329  *
330  ******************************************************************************/
331 
332 static void
333 TrAmlSetSubtreeParent (
334     ACPI_PARSE_OBJECT       *Op,
335     ACPI_PARSE_OBJECT       *Parent)
336 {
337     ACPI_PARSE_OBJECT       *Next;
338 
339 
340     Next = Op;
341     while (Next)
342     {
343         Next->Asl.Parent = Parent;
344         Next = Next->Asl.Next;
345     }
346 }
347 
348 
349 /*******************************************************************************
350  *
351  * FUNCTION:    TrAmlInsertPeer
352  *
353  * PARAMETERS:  Op              - First node in a list of peer nodes
354  *              NewPeer         - Peer node to insert
355  *
356  * RETURN:      None
357  *
358  * DESCRIPTION: Insert a new peer node into a list of peers.
359  *
360  ******************************************************************************/
361 
362 static void
363 TrAmlInsertPeer (
364     ACPI_PARSE_OBJECT       *Op,
365     ACPI_PARSE_OBJECT       *NewPeer)
366 {
367 
368     NewPeer->Asl.Next = Op->Asl.Next;
369     Op->Asl.Next = NewPeer;
370 }
371 
372 
373 /*******************************************************************************
374  *
375  * FUNCTION:    TrAmlTransformWalkBegin
376  *
377  * PARAMETERS:  ASL_WALK_CALLBACK
378  *
379  * RETURN:      None
380  *
381  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
382  *              operands.
383  *
384  ******************************************************************************/
385 
386 ACPI_STATUS
387 TrAmlTransformWalkBegin (
388     ACPI_PARSE_OBJECT       *Op,
389     UINT32                  Level,
390     void                    *Context)
391 {
392 
393     TrTransformSubtree (Op);
394     return (AE_OK);
395 }
396 
397 
398 /*******************************************************************************
399  *
400  * FUNCTION:    TrAmlTransformWalkEnd
401  *
402  * PARAMETERS:  ASL_WALK_CALLBACK
403  *
404  * RETURN:      None
405  *
406  * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
407  *              operands.
408  *
409  ******************************************************************************/
410 
411 ACPI_STATUS
412 TrAmlTransformWalkEnd (
413     ACPI_PARSE_OBJECT       *Op,
414     UINT32                  Level,
415     void                    *Context)
416 {
417 
418     /* Save possible Externals list in the DefintionBlock Op */
419 
420     if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK)
421     {
422         Op->Asl.Value.Arg = AslGbl_ExternalsListHead;
423         AslGbl_ExternalsListHead = NULL;
424     }
425 
426     return (AE_OK);
427 }
428 
429 
430 /*******************************************************************************
431  *
432  * FUNCTION:    TrTransformSubtree
433  *
434  * PARAMETERS:  Op        - The parent parse node
435  *
436  * RETURN:      None
437  *
438  * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
439  *              complex AML opcodes require processing of the child nodes
440  *              (arguments/operands).
441  *
442  ******************************************************************************/
443 
444 static void
445 TrTransformSubtree (
446     ACPI_PARSE_OBJECT           *Op)
447 {
448     ACPI_PARSE_OBJECT           *MethodOp;
449     ACPI_NAMESTRING_INFO        Info;
450 
451 
452     if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
453     {
454         return;
455     }
456 
457     switch (Op->Asl.ParseOpcode)
458     {
459     case PARSEOP_DEFINITION_BLOCK:
460 
461         TrDoDefinitionBlock (Op);
462         break;
463 
464     case PARSEOP_SWITCH:
465 
466         TrDoSwitch (Op);
467         break;
468 
469     case PARSEOP_METHOD:
470 
471         TrDoMethod (Op);
472         break;
473 
474     case PARSEOP_EXTERNAL:
475 
476         ExDoExternal (Op);
477         break;
478 
479     case PARSEOP___METHOD__:
480 
481         /* Transform to a string op containing the parent method name */
482 
483         Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
484         UtSetParseOpName (Op);
485 
486         /* Find the parent control method op */
487 
488         MethodOp = Op;
489         while (MethodOp)
490         {
491             if (MethodOp->Asl.ParseOpcode == PARSEOP_METHOD)
492             {
493                 /* First child contains the method name */
494 
495                 MethodOp = MethodOp->Asl.Child;
496                 Op->Asl.Value.String = MethodOp->Asl.Value.String;
497                 return;
498             }
499 
500             MethodOp = MethodOp->Asl.Parent;
501         }
502 
503         /* At the root, invocation not within a control method */
504 
505         Op->Asl.Value.String = "\\";
506         break;
507 
508     case PARSEOP_NAMESTRING:
509         /*
510          * A NameString can be up to 255 (0xFF) individual NameSegs maximum
511          * (with 254 dot separators) - as per the ACPI specification. Note:
512          * Cannot check for NumSegments == 0 because things like
513          * Scope(\) are legal and OK.
514          */
515         Info.ExternalName = Op->Asl.Value.String;
516         AcpiNsGetInternalNameLength (&Info);
517 
518         if (Info.NumSegments > 255)
519         {
520             AslError (ASL_ERROR, ASL_MSG_NAMESTRING_LENGTH, Op, NULL);
521         }
522         break;
523 
524     case PARSEOP_UNLOAD:
525 
526         AslError (ASL_WARNING, ASL_MSG_UNLOAD, Op, NULL);
527         break;
528 
529     case PARSEOP_SLEEP:
530 
531         /* Remark for very long sleep values */
532 
533         if (Op->Asl.Child->Asl.Value.Integer > 1000)
534         {
535             AslError (ASL_REMARK, ASL_MSG_LONG_SLEEP, Op, NULL);
536         }
537         break;
538 
539     case PARSEOP_PROCESSOR:
540 
541         AslError (ASL_WARNING, ASL_MSG_LEGACY_PROCESSOR_OP, Op, Op->Asl.ExternalName);
542         break;
543 
544     default:
545 
546         /* Nothing to do here for other opcodes */
547 
548         break;
549     }
550 }
551 
552 
553 /*******************************************************************************
554  *
555  * FUNCTION:    TrDoDefinitionBlock
556  *
557  * PARAMETERS:  Op        - Parse node
558  *
559  * RETURN:      None
560  *
561  * DESCRIPTION: Find the end of the definition block and set a global to this
562  *              node. It is used by the compiler to insert compiler-generated
563  *              names at the root level of the namespace.
564  *
565  ******************************************************************************/
566 
567 static void
568 TrDoDefinitionBlock (
569     ACPI_PARSE_OBJECT       *Op)
570 {
571     ACPI_PARSE_OBJECT       *Next;
572     UINT32                  i;
573 
574 
575     /* Reset external list when starting a definition block */
576 
577     AslGbl_ExternalsListHead = NULL;
578 
579     Next = Op->Asl.Child;
580     for (i = 0; i < 5; i++)
581     {
582         Next = Next->Asl.Next;
583         if (i == 0)
584         {
585             /*
586              * This is the table signature. Only the DSDT can be assumed
587              * to be at the root of the namespace;  Therefore, namepath
588              * optimization can only be performed on the DSDT.
589              */
590             if (!ACPI_COMPARE_NAMESEG (Next->Asl.Value.String, ACPI_SIG_DSDT))
591             {
592                 AslGbl_ReferenceOptimizationFlag = FALSE;
593             }
594         }
595     }
596 
597     AslGbl_FirstLevelInsertionNode = Next;
598 }
599 
600 
601 /*******************************************************************************
602  *
603  * FUNCTION:    TrDoSwitch
604  *
605  * PARAMETERS:  StartNode        - Parse node for SWITCH
606  *
607  * RETURN:      None
608  *
609  * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is
610  *              no actual AML opcode for SWITCH -- it must be simulated.
611  *
612  ******************************************************************************/
613 
614 static void
615 TrDoSwitch (
616     ACPI_PARSE_OBJECT       *StartNode)
617 {
618     ACPI_PARSE_OBJECT       *Next;
619     ACPI_PARSE_OBJECT       *CaseOp = NULL;
620     ACPI_PARSE_OBJECT       *CaseBlock = NULL;
621     ACPI_PARSE_OBJECT       *DefaultOp = NULL;
622     ACPI_PARSE_OBJECT       *CurrentParentNode;
623     ACPI_PARSE_OBJECT       *Conditional = NULL;
624     ACPI_PARSE_OBJECT       *Predicate;
625     ACPI_PARSE_OBJECT       *Peer;
626     ACPI_PARSE_OBJECT       *NewOp;
627     ACPI_PARSE_OBJECT       *NewOp2;
628     ACPI_PARSE_OBJECT       *MethodOp;
629     ACPI_PARSE_OBJECT       *StoreOp;
630     ACPI_PARSE_OBJECT       *BreakOp;
631     ACPI_PARSE_OBJECT       *BufferOp;
632     char                    *PredicateValueName;
633     UINT16                  Index;
634     UINT32                  Btype;
635 
636 
637     /* Start node is the Switch() node */
638 
639     CurrentParentNode  = StartNode;
640 
641     /* Create a new temp name of the form _T_x */
642 
643     PredicateValueName = TrAmlGetNextTempName (StartNode, &AslGbl_TempCount);
644     if (!PredicateValueName)
645     {
646         return;
647     }
648 
649     /* First child is the Switch() predicate */
650 
651     Next = StartNode->Asl.Child;
652 
653     /*
654      * Examine the return type of the Switch Value -
655      * must be Integer/Buffer/String
656      */
657     Index = (UINT16) (Next->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
658     Btype = AslKeywordMapping[Index].AcpiBtype;
659     if ((Btype != ACPI_BTYPE_INTEGER) &&
660         (Btype != ACPI_BTYPE_STRING)  &&
661         (Btype != ACPI_BTYPE_BUFFER))
662     {
663         AslError (ASL_WARNING, ASL_MSG_SWITCH_TYPE, Next, NULL);
664         Btype = ACPI_BTYPE_INTEGER;
665     }
666 
667     /* CASE statements start at next child */
668 
669     Peer = Next->Asl.Next;
670     while (Peer)
671     {
672         Next = Peer;
673         Peer = Next->Asl.Next;
674 
675         if (Next->Asl.ParseOpcode == PARSEOP_CASE)
676         {
677             TrCheckForDuplicateCase (Next, Next->Asl.Child);
678 
679             if (CaseOp)
680             {
681                 /* Add an ELSE to complete the previous CASE */
682 
683                 NewOp = TrCreateLeafOp (PARSEOP_ELSE);
684                 NewOp->Asl.Parent = Conditional->Asl.Parent;
685                 TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent);
686 
687                 /* Link ELSE node as a peer to the previous IF */
688 
689                 TrAmlInsertPeer (Conditional, NewOp);
690                 CurrentParentNode = NewOp;
691             }
692 
693             CaseOp = Next;
694             Conditional = CaseOp;
695             CaseBlock = CaseOp->Asl.Child->Asl.Next;
696             Conditional->Asl.Child->Asl.Next = NULL;
697             Predicate = CaseOp->Asl.Child;
698 
699             if ((Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
700                 (Predicate->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
701             {
702                 /*
703                  * Convert the package declaration to this form:
704                  *
705                  * If (LNotEqual (Match (Package(<size>){<data>},
706                  *                       MEQ, _T_x, MTR, Zero, Zero), Ones))
707                  */
708                 NewOp2              = TrCreateLeafOp (PARSEOP_MATCHTYPE_MEQ);
709                 Predicate->Asl.Next = NewOp2;
710                 TrAmlInitLineNumbers (NewOp2, Conditional);
711 
712                 NewOp               = NewOp2;
713                 NewOp2              = TrCreateValuedLeafOp (PARSEOP_NAMESTRING,
714                                         (UINT64) ACPI_TO_INTEGER (PredicateValueName));
715                 NewOp->Asl.Next     = NewOp2;
716                 TrAmlInitLineNumbers (NewOp2, Predicate);
717 
718                 NewOp               = NewOp2;
719                 NewOp2              = TrCreateLeafOp (PARSEOP_MATCHTYPE_MTR);
720                 NewOp->Asl.Next     = NewOp2;
721                 TrAmlInitLineNumbers (NewOp2, Predicate);
722 
723                 NewOp               = NewOp2;
724                 NewOp2              = TrCreateLeafOp (PARSEOP_ZERO);
725                 NewOp->Asl.Next     = NewOp2;
726                 TrAmlInitLineNumbers (NewOp2, Predicate);
727 
728                 NewOp               = NewOp2;
729                 NewOp2              = TrCreateLeafOp (PARSEOP_ZERO);
730                 NewOp->Asl.Next     = NewOp2;
731                 TrAmlInitLineNumbers (NewOp2, Predicate);
732 
733                 NewOp2              = TrCreateLeafOp (PARSEOP_MATCH);
734                 NewOp2->Asl.Child   = Predicate;  /* PARSEOP_PACKAGE */
735                 TrAmlInitLineNumbers (NewOp2, Conditional);
736                 TrAmlSetSubtreeParent (Predicate, NewOp2);
737 
738                 NewOp               = NewOp2;
739                 NewOp2              = TrCreateLeafOp (PARSEOP_ONES);
740                 NewOp->Asl.Next     = NewOp2;
741                 TrAmlInitLineNumbers (NewOp2, Conditional);
742 
743                 NewOp2              = TrCreateLeafOp (PARSEOP_LEQUAL);
744                 NewOp2->Asl.Child   = NewOp;
745                 NewOp->Asl.Parent   = NewOp2;
746                 TrAmlInitLineNumbers (NewOp2, Conditional);
747                 TrAmlSetSubtreeParent (NewOp, NewOp2);
748 
749                 NewOp               = NewOp2;
750                 NewOp2              = TrCreateLeafOp (PARSEOP_LNOT);
751                 NewOp2->Asl.Child   = NewOp;
752                 NewOp2->Asl.Parent  = Conditional;
753                 NewOp->Asl.Parent   = NewOp2;
754                 TrAmlInitLineNumbers (NewOp2, Conditional);
755 
756                 Conditional->Asl.Child = NewOp2;
757                 NewOp2->Asl.Next = CaseBlock;
758             }
759             else
760             {
761                 /*
762                  * Integer and Buffer case.
763                  *
764                  * Change CaseOp() to:  If (LEqual (SwitchValue, CaseValue)) {...}
765                  * Note: SwitchValue is first to allow the CaseValue to be implicitly
766                  * converted to the type of SwitchValue if necessary.
767                  *
768                  * CaseOp->Child is the case value
769                  * CaseOp->Child->Peer is the beginning of the case block
770                  */
771                 NewOp = TrCreateValuedLeafOp (PARSEOP_NAMESTRING,
772                     (UINT64) ACPI_TO_INTEGER (PredicateValueName));
773                 NewOp->Asl.Next = Predicate;
774                 TrAmlInitLineNumbers (NewOp, Predicate);
775 
776                 NewOp2              = TrCreateLeafOp (PARSEOP_LEQUAL);
777                 NewOp2->Asl.Parent  = Conditional;
778                 NewOp2->Asl.Child   = NewOp;
779                 TrAmlInitLineNumbers (NewOp2, Conditional);
780 
781                 TrAmlSetSubtreeParent (NewOp, NewOp2);
782 
783                 Predicate           = NewOp2;
784                 Predicate->Asl.Next = CaseBlock;
785 
786                 TrAmlSetSubtreeParent (Predicate, Conditional);
787                 Conditional->Asl.Child = Predicate;
788             }
789 
790             /* Reinitialize the CASE node to an IF node */
791 
792             TrAmlInitNode (Conditional, PARSEOP_IF);
793 
794             /*
795              * The first CASE(IF) is not nested under an ELSE.
796              * All other CASEs are children of a parent ELSE.
797              */
798             if (CurrentParentNode == StartNode)
799             {
800                 Conditional->Asl.Next = NULL;
801             }
802             else
803             {
804                 /*
805                  * The IF is a child of previous IF/ELSE. It
806                  * is therefore without peer.
807                  */
808                 CurrentParentNode->Asl.Child = Conditional;
809                 Conditional->Asl.Parent      = CurrentParentNode;
810                 Conditional->Asl.Next        = NULL;
811             }
812         }
813         else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT)
814         {
815             if (DefaultOp)
816             {
817                 /*
818                  * More than one Default
819                  * (Parser does not catch this, must check here)
820                  */
821                 AslError (ASL_ERROR, ASL_MSG_MULTIPLE_DEFAULT, Next, NULL);
822             }
823             else
824             {
825                 /* Save the DEFAULT node for later, after CASEs */
826 
827                 DefaultOp = Next;
828             }
829         }
830         else
831         {
832             /* Unknown peer opcode */
833 
834             AcpiOsPrintf ("Unknown parse opcode for switch statement: %s (%u)\n",
835                 Next->Asl.ParseOpName, Next->Asl.ParseOpcode);
836         }
837     }
838 
839     /* Add the default case at the end of the if/else construct */
840 
841     if (DefaultOp)
842     {
843         /* If no CASE statements, this is an error - see below */
844 
845         if (CaseOp)
846         {
847             /* Convert the DEFAULT node to an ELSE */
848 
849             TrAmlInitNode (DefaultOp, PARSEOP_ELSE);
850             DefaultOp->Asl.Parent = Conditional->Asl.Parent;
851 
852             /* Link ELSE node as a peer to the previous IF */
853 
854             TrAmlInsertPeer (Conditional, DefaultOp);
855         }
856     }
857 
858     if (!CaseOp)
859     {
860         AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL);
861     }
862 
863 
864     /*
865      * Create a Name(_T_x, ...) statement. This statement must appear at the
866      * method level, in case a loop surrounds the switch statement and could
867      * cause the name to be created twice (error).
868      */
869 
870     /* Create the Name node */
871 
872     Predicate = StartNode->Asl.Child;
873     NewOp = TrCreateLeafOp (PARSEOP_NAME);
874     TrAmlInitLineNumbers (NewOp, StartNode);
875 
876     /* Find the parent method */
877 
878     Next = StartNode;
879     while ((Next->Asl.ParseOpcode != PARSEOP_METHOD) &&
880            (Next->Asl.ParseOpcode != PARSEOP_DEFINITION_BLOCK))
881     {
882         Next = Next->Asl.Parent;
883     }
884     MethodOp = Next;
885 
886     NewOp->Asl.CompileFlags |= OP_COMPILER_EMITTED;
887     NewOp->Asl.Parent = Next;
888 
889     /* Insert name after the method name and arguments */
890 
891     Next = Next->Asl.Child; /* Name */
892     Next = Next->Asl.Next;  /* NumArgs */
893     Next = Next->Asl.Next;  /* SerializeRule */
894 
895     /*
896      * If method is not Serialized, we must make is so, because of the way
897      * that Switch() must be implemented -- we cannot allow multiple threads
898      * to execute this method concurrently since we need to create local
899      * temporary name(s).
900      */
901     if (Next->Asl.ParseOpcode != PARSEOP_SERIALIZERULE_SERIAL)
902     {
903         AslError (ASL_REMARK, ASL_MSG_SERIALIZED, MethodOp,
904             "Due to use of Switch operator");
905         Next->Asl.ParseOpcode = PARSEOP_SERIALIZERULE_SERIAL;
906     }
907 
908     Next = Next->Asl.Next;  /* SyncLevel */
909     Next = Next->Asl.Next;  /* ReturnType */
910     Next = Next->Asl.Next;  /* ParameterTypes */
911 
912     TrAmlInsertPeer (Next, NewOp);
913     TrAmlInitLineNumbers (NewOp, Next);
914 
915     /* Create the NameSeg child for the Name node */
916 
917     NewOp2 = TrCreateValuedLeafOp (PARSEOP_NAMESEG,
918         (UINT64) ACPI_TO_INTEGER (PredicateValueName));
919     TrAmlInitLineNumbers (NewOp2, NewOp);
920     NewOp2->Asl.CompileFlags |= OP_IS_NAME_DECLARATION;
921     NewOp->Asl.Child  = NewOp2;
922 
923     /* Create the initial value for the Name. Btype was already validated above */
924 
925     switch (Btype)
926     {
927     case ACPI_BTYPE_INTEGER:
928 
929         NewOp2->Asl.Next = TrCreateValuedLeafOp (PARSEOP_ZERO,
930             (UINT64) 0);
931         TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
932         break;
933 
934     case ACPI_BTYPE_STRING:
935 
936         NewOp2->Asl.Next = TrCreateValuedLeafOp (PARSEOP_STRING_LITERAL,
937             (UINT64) ACPI_TO_INTEGER (""));
938         TrAmlInitLineNumbers (NewOp2->Asl.Next, NewOp);
939         break;
940 
941     case ACPI_BTYPE_BUFFER:
942 
943         (void) TrLinkPeerOp (NewOp2, TrCreateValuedLeafOp (PARSEOP_BUFFER,
944             (UINT64) 0));
945         Next = NewOp2->Asl.Next;
946         TrAmlInitLineNumbers (Next, NewOp2);
947 
948         (void) TrLinkOpChildren (Next, 1, TrCreateValuedLeafOp (PARSEOP_ZERO,
949             (UINT64) 1));
950         TrAmlInitLineNumbers (Next->Asl.Child, Next);
951 
952         BufferOp = TrCreateValuedLeafOp (PARSEOP_DEFAULT_ARG, (UINT64) 0);
953         TrAmlInitLineNumbers (BufferOp, Next->Asl.Child);
954         (void) TrLinkPeerOp (Next->Asl.Child, BufferOp);
955 
956         TrAmlSetSubtreeParent (Next->Asl.Child, Next);
957         break;
958 
959     default:
960 
961         break;
962     }
963 
964     TrAmlSetSubtreeParent (NewOp2, NewOp);
965 
966     /*
967      * Transform the Switch() into a While(One)-Break node.
968      * And create a Store() node which will be used to save the
969      * Switch() value. The store is of the form: Store (Value, _T_x)
970      * where _T_x is the temp variable.
971      */
972     TrAmlInitNode (StartNode, PARSEOP_WHILE);
973     NewOp = TrCreateLeafOp (PARSEOP_ONE);
974     TrAmlInitLineNumbers (NewOp, StartNode);
975     NewOp->Asl.Next = Predicate->Asl.Next;
976     NewOp->Asl.Parent = StartNode;
977     StartNode->Asl.Child = NewOp;
978 
979     /* Create a Store() node */
980 
981     StoreOp = TrCreateLeafOp (PARSEOP_STORE);
982     TrAmlInitLineNumbers (StoreOp, NewOp);
983     StoreOp->Asl.Parent = StartNode;
984     TrAmlInsertPeer (NewOp, StoreOp);
985 
986     /* Complete the Store subtree */
987 
988     StoreOp->Asl.Child = Predicate;
989     Predicate->Asl.Parent = StoreOp;
990 
991     NewOp = TrCreateValuedLeafOp (PARSEOP_NAMESEG,
992         (UINT64) ACPI_TO_INTEGER (PredicateValueName));
993     TrAmlInitLineNumbers (NewOp, StoreOp);
994     NewOp->Asl.Parent    = StoreOp;
995     Predicate->Asl.Next  = NewOp;
996 
997     /* Create a Break() node and insert it into the end of While() */
998 
999     Conditional = StartNode->Asl.Child;
1000     while (Conditional->Asl.Next)
1001     {
1002         Conditional = Conditional->Asl.Next;
1003     }
1004 
1005     BreakOp = TrCreateLeafOp (PARSEOP_BREAK);
1006     TrAmlInitLineNumbers (BreakOp, NewOp);
1007     BreakOp->Asl.Parent = StartNode;
1008     TrAmlInsertPeer (Conditional, BreakOp);
1009 }
1010 
1011 
1012 /*******************************************************************************
1013  *
1014  * FUNCTION:    TrCheckForDuplicateCase
1015  *
1016  * PARAMETERS:  CaseOp          - Parse node for first Case statement in list
1017  *              Predicate1      - Case value for the input CaseOp
1018  *
1019  * RETURN:      None
1020  *
1021  * DESCRIPTION: Check for duplicate case values. Currently, only handles
1022  *              Integers, Strings and Buffers. No support for Package objects.
1023  *
1024  ******************************************************************************/
1025 
1026 static void
1027 TrCheckForDuplicateCase (
1028     ACPI_PARSE_OBJECT       *CaseOp,
1029     ACPI_PARSE_OBJECT       *Predicate1)
1030 {
1031     ACPI_PARSE_OBJECT       *Next;
1032     ACPI_PARSE_OBJECT       *Predicate2;
1033 
1034 
1035     /* Walk the list of CASE opcodes */
1036 
1037     Next = CaseOp->Asl.Next;
1038     while (Next)
1039     {
1040         if (Next->Asl.ParseOpcode == PARSEOP_CASE)
1041         {
1042             /* Emit error only once */
1043 
1044             if (Next->Asl.CompileFlags & OP_IS_DUPLICATE)
1045             {
1046                 goto NextCase;
1047             }
1048 
1049             /* Check for a duplicate plain integer */
1050 
1051             Predicate2 = Next->Asl.Child;
1052             if ((Predicate1->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1053                 (Predicate2->Asl.ParseOpcode == PARSEOP_INTEGER))
1054             {
1055                 if (Predicate1->Asl.Value.Integer == Predicate2->Asl.Value.Integer)
1056                 {
1057                     goto FoundDuplicate;
1058                 }
1059             }
1060 
1061             /* Check for pairs of the constants ZERO, ONE, ONES */
1062 
1063             else if (((Predicate1->Asl.ParseOpcode == PARSEOP_ZERO) &&
1064                 (Predicate2->Asl.ParseOpcode == PARSEOP_ZERO)) ||
1065                 ((Predicate1->Asl.ParseOpcode == PARSEOP_ONE) &&
1066                 (Predicate2->Asl.ParseOpcode == PARSEOP_ONE)) ||
1067                 ((Predicate1->Asl.ParseOpcode == PARSEOP_ONES) &&
1068                 (Predicate2->Asl.ParseOpcode == PARSEOP_ONES)))
1069             {
1070                 goto FoundDuplicate;
1071             }
1072 
1073             /* Check for a duplicate string constant (literal) */
1074 
1075             else if ((Predicate1->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) &&
1076                 (Predicate2->Asl.ParseOpcode == PARSEOP_STRING_LITERAL))
1077             {
1078                 if (!strcmp (Predicate1->Asl.Value.String,
1079                         Predicate2->Asl.Value.String))
1080                 {
1081                     goto FoundDuplicate;
1082                 }
1083             }
1084 
1085             /* Check for a duplicate buffer constant */
1086 
1087             else if ((Predicate1->Asl.ParseOpcode == PARSEOP_BUFFER) &&
1088                 (Predicate2->Asl.ParseOpcode == PARSEOP_BUFFER))
1089             {
1090                 if (TrCheckForBufferMatch (Predicate1->Asl.Child,
1091                         Predicate2->Asl.Child))
1092                 {
1093                     goto FoundDuplicate;
1094                 }
1095             }
1096         }
1097         goto NextCase;
1098 
1099 FoundDuplicate:
1100         /* Emit error message only once */
1101 
1102         Next->Asl.CompileFlags |= OP_IS_DUPLICATE;
1103 
1104         AslDualParseOpError (ASL_ERROR, ASL_MSG_DUPLICATE_CASE, Next,
1105             Next->Asl.Value.String, ASL_MSG_CASE_FOUND_HERE, CaseOp,
1106             CaseOp->Asl.ExternalName);
1107 
1108 NextCase:
1109         Next = Next->Asl.Next;
1110     }
1111 }
1112 
1113 /*******************************************************************************
1114  *
1115  * FUNCTION:    TrBufferIsAllZero
1116  *
1117  * PARAMETERS:  Op          - Parse node for first opcode in buffer initializer
1118  *                            list
1119  *
1120  * RETURN:      TRUE if buffer contains all zeros or a DEFAULT_ARG
1121  *
1122  * DESCRIPTION: Check for duplicate Buffer case values.
1123  *
1124  ******************************************************************************/
1125 
1126 static BOOLEAN
1127 TrBufferIsAllZero (
1128     ACPI_PARSE_OBJECT       *Op)
1129 {
1130     while (Op)
1131     {
1132         if (Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1133         {
1134             return (TRUE);
1135         }
1136         else if (Op->Asl.Value.Integer != 0)
1137         {
1138             return (FALSE);
1139         }
1140 
1141         Op = Op->Asl.Next;
1142     }
1143 
1144     return (TRUE);
1145 }
1146 
1147 
1148 /*******************************************************************************
1149  *
1150  * FUNCTION:    TrCheckForBufferMatch
1151  *
1152  * PARAMETERS:  Next1       - Parse node for first opcode in first buffer list
1153  *                              (The DEFAULT_ARG or INTEGER node)
1154  *              Next2       - Parse node for first opcode in second buffer list
1155  *                              (The DEFAULT_ARG or INTEGER node)
1156  *
1157  * RETURN:      TRUE if buffers match, FALSE otherwise
1158  *
1159  * DESCRIPTION: Check for duplicate Buffer case values.
1160  *
1161  ******************************************************************************/
1162 
1163 static BOOLEAN
1164 TrCheckForBufferMatch (
1165     ACPI_PARSE_OBJECT       *NextOp1,
1166     ACPI_PARSE_OBJECT       *NextOp2)
1167 {
1168     /*
1169      * The buffer length can be a DEFAULT_ARG or INTEGER. If any of the nodes
1170      * are DEFAULT_ARG, it means that the length has yet to be computed.
1171      * However, the initializer list can be compared to determine if these two
1172      * buffers match.
1173      */
1174     if ((NextOp1->Asl.ParseOpcode == PARSEOP_INTEGER &&
1175         NextOp2->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1176         NextOp1->Asl.Value.Integer != NextOp2->Asl.Value.Integer)
1177     {
1178         return (FALSE);
1179     }
1180 
1181     /*
1182      * Buffers that have explicit lengths but no initializer lists are
1183      * filled with zeros at runtime. This is equivalent to buffers that have the
1184      * same length that are filled with zeros.
1185      *
1186      * In other words, the following buffers are equivalent:
1187      *
1188      * Buffer(0x4) {}
1189      * Buffer() {0x0, 0x0, 0x0, 0x0}
1190      *
1191      * This statement checks for matches where one buffer does not have an
1192      * initializer list and another buffer contains all zeros.
1193      */
1194     if (NextOp1->Asl.ParseOpcode != NextOp2->Asl.ParseOpcode &&
1195         TrBufferIsAllZero (NextOp1->Asl.Next) &&
1196         TrBufferIsAllZero (NextOp2->Asl.Next))
1197     {
1198         return (TRUE);
1199     }
1200 
1201     /* Start at the BYTECONST initializer node list */
1202 
1203     NextOp1 = NextOp1->Asl.Next;
1204     NextOp2 = NextOp2->Asl.Next;
1205 
1206     /*
1207      * Walk both lists until either a mismatch is found, or one or more
1208      * end-of-lists are found
1209      */
1210     while (NextOp1 && NextOp2)
1211     {
1212         if ((NextOp1->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) &&
1213             (NextOp2->Asl.ParseOpcode == PARSEOP_STRING_LITERAL))
1214         {
1215             if (!strcmp (NextOp1->Asl.Value.String, NextOp2->Asl.Value.String))
1216             {
1217                 return (TRUE);
1218             }
1219             else
1220             {
1221                 return (FALSE);
1222             }
1223         }
1224         if ((UINT8) NextOp1->Asl.Value.Integer != (UINT8) NextOp2->Asl.Value.Integer)
1225         {
1226             return (FALSE);
1227         }
1228 
1229         NextOp1 = NextOp1->Asl.Next;
1230         NextOp2 = NextOp2->Asl.Next;
1231     }
1232 
1233     /* Not a match if one of the lists is not at end-of-list */
1234 
1235     if (NextOp1 || NextOp2)
1236     {
1237         return (FALSE);
1238     }
1239 
1240     /* Otherwise, the buffers match */
1241 
1242     return (TRUE);
1243 }
1244 
1245 
1246 /*******************************************************************************
1247  *
1248  * FUNCTION:    TrDoMethod
1249  *
1250  * PARAMETERS:  Op               - Parse node for SWITCH
1251  *
1252  * RETURN:      None
1253  *
1254  * DESCRIPTION: Determine that parameter count of an ASL method node by
1255  *              translating the parameter count parse node from
1256  *              PARSEOP_DEFAULT_ARG to PARSEOP_BYTECONST.
1257  *
1258  ******************************************************************************/
1259 
1260 static void
1261 TrDoMethod (
1262     ACPI_PARSE_OBJECT       *Op)
1263 {
1264     ACPI_PARSE_OBJECT           *ArgCountOp;
1265     UINT8                       ArgCount;
1266     ACPI_PARSE_OBJECT           *ParameterOp;
1267 
1268 
1269     /*
1270      * TBD: Zero the tempname (_T_x) count. Probably shouldn't be a global,
1271      * however
1272      */
1273     AslGbl_TempCount = 0;
1274 
1275     ArgCountOp = Op->Asl.Child->Asl.Next;
1276     if (ArgCountOp->Asl.ParseOpcode == PARSEOP_BYTECONST)
1277     {
1278         /*
1279          * Parameter count for this method has already been recorded in the
1280          * method declaration.
1281          */
1282         return;
1283     }
1284 
1285     /*
1286      * Parameter count has been omitted in the method declaration.
1287      * Count the amount of arguments here.
1288      */
1289     ParameterOp = ArgCountOp->Asl.Next->Asl.Next->Asl.Next->Asl.Next;
1290     if (ParameterOp->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
1291     {
1292         ArgCount = 0;
1293         ParameterOp = ParameterOp->Asl.Child;
1294 
1295         while (ParameterOp)
1296         {
1297             ParameterOp = ParameterOp->Asl.Next;
1298             ArgCount++;
1299         }
1300 
1301         ArgCountOp->Asl.Value.Integer = ArgCount;
1302         ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
1303     }
1304     else
1305     {
1306         /*
1307          * Method parameters can be counted by analyzing the Parameter type
1308          * list. If the Parameter list contains more than 1 parameter, it
1309          * is nested under PARSEOP_DEFAULT_ARG. When there is only 1
1310          * parameter, the parse tree contains a single node representing
1311          * that type.
1312          */
1313         ArgCountOp->Asl.Value.Integer = 1;
1314         ArgCountOp->Asl.ParseOpcode = PARSEOP_BYTECONST;
1315     }
1316 }
1317