OSDN Git Service

klibc基本機能実装. ACPICAの準備
[vaneos/DivergeMirror.git] / drivers / acpi / components / disassembler / dmcstyle.c
1 /*******************************************************************************
2  *
3  * Module Name: dmcstyle - Support for C-style operator disassembly
4  *
5  ******************************************************************************/
6
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2015, 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 #include "acpi.h"
117 #include "accommon.h"
118 #include "acparser.h"
119 #include "amlcode.h"
120 #include "acdisasm.h"
121 #include "acdebug.h"
122
123 #ifdef ACPI_DISASSEMBLER
124
125 #define _COMPONENT          ACPI_CA_DEBUGGER
126         ACPI_MODULE_NAME    ("dmcstyle")
127
128
129 /* Local prototypes */
130
131 static char *
132 AcpiDmGetCompoundSymbol (
133    UINT16                   AslOpcode);
134
135 static void
136 AcpiDmPromoteTarget (
137     ACPI_PARSE_OBJECT       *Op,
138     ACPI_PARSE_OBJECT       *Target);
139
140 static BOOLEAN
141 AcpiDmIsValidTarget (
142     ACPI_PARSE_OBJECT       *Op);
143
144 static BOOLEAN
145 AcpiDmIsTargetAnOperand (
146     ACPI_PARSE_OBJECT       *Target,
147     ACPI_PARSE_OBJECT       *Operand,
148     BOOLEAN                 TopLevel);
149
150
151 /*******************************************************************************
152  *
153  * FUNCTION:    AcpiDmCheckForSymbolicOpcode
154  *
155  * PARAMETERS:  Op                  - Current parse object
156  *              Walk                - Current parse tree walk info
157  *
158  * RETURN:      TRUE if opcode can be converted to symbolic, FALSE otherwise
159  *
160  * DESCRIPTION: This is the main code that implements disassembly of AML code
161  *              to C-style operators. Called during descending phase of the
162  *              parse tree walk.
163  *
164  ******************************************************************************/
165
166 BOOLEAN
167 AcpiDmCheckForSymbolicOpcode (
168     ACPI_PARSE_OBJECT       *Op,
169     ACPI_OP_WALK_INFO       *Info)
170 {
171     char                    *OperatorSymbol = NULL;
172     ACPI_PARSE_OBJECT       *Child1;
173     ACPI_PARSE_OBJECT       *Child2;
174     ACPI_PARSE_OBJECT       *Target;
175
176
177     /* Exit immediately if ASL+ not enabled */
178
179     if (!AcpiGbl_CstyleDisassembly)
180     {
181         return (FALSE);
182     }
183
184     /* Get the first operand */
185
186     Child1 = AcpiPsGetArg (Op, 0);
187     if (!Child1)
188     {
189         return (FALSE);
190     }
191
192     /* Get the second operand */
193
194     Child2 = Child1->Common.Next;
195
196     /* Setup the operator string for this opcode */
197
198     switch (Op->Common.AmlOpcode)
199     {
200     case AML_ADD_OP:
201         OperatorSymbol = " + ";
202         break;
203
204     case AML_SUBTRACT_OP:
205         OperatorSymbol = " - ";
206         break;
207
208     case AML_MULTIPLY_OP:
209         OperatorSymbol = " * ";
210         break;
211
212     case AML_DIVIDE_OP:
213         OperatorSymbol = " / ";
214         break;
215
216     case AML_MOD_OP:
217         OperatorSymbol = " % ";
218         break;
219
220     case AML_SHIFT_LEFT_OP:
221         OperatorSymbol = " << ";
222         break;
223
224     case AML_SHIFT_RIGHT_OP:
225         OperatorSymbol = " >> ";
226         break;
227
228     case AML_BIT_AND_OP:
229         OperatorSymbol = " & ";
230         break;
231
232     case AML_BIT_OR_OP:
233         OperatorSymbol = " | ";
234         break;
235
236     case AML_BIT_XOR_OP:
237         OperatorSymbol = " ^ ";
238         break;
239
240     /* Logical operators, no target */
241
242     case AML_LAND_OP:
243         OperatorSymbol = " && ";
244         break;
245
246     case AML_LEQUAL_OP:
247         OperatorSymbol = " == ";
248         break;
249
250     case AML_LGREATER_OP:
251         OperatorSymbol = " > ";
252         break;
253
254     case AML_LLESS_OP:
255         OperatorSymbol = " < ";
256         break;
257
258     case AML_LOR_OP:
259         OperatorSymbol = " || ";
260         break;
261
262     case AML_LNOT_OP:
263         /*
264          * Check for the LNOT sub-opcodes. These correspond to
265          * LNotEqual, LLessEqual, and LGreaterEqual. There are
266          * no actual AML opcodes for these operators.
267          */
268         switch (Child1->Common.AmlOpcode)
269         {
270         case AML_LEQUAL_OP:
271             OperatorSymbol = " != ";
272             break;
273
274         case AML_LGREATER_OP:
275             OperatorSymbol = " <= ";
276             break;
277
278         case AML_LLESS_OP:
279             OperatorSymbol = " >= ";
280             break;
281
282         default:
283
284             /* Unary LNOT case, emit "!" immediately */
285
286             AcpiOsPrintf ("!");
287             return (TRUE);
288         }
289
290         Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
291         Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
292
293         /* Save symbol string in the next child (not peer) */
294
295         Child2 = AcpiPsGetArg (Child1, 0);
296         if (!Child2)
297         {
298             return (FALSE);
299         }
300
301         Child2->Common.OperatorSymbol = OperatorSymbol;
302         return (TRUE);
303
304 #ifdef INDEX_SUPPORT
305     case AML_INDEX_OP:
306         Child1->Common.OperatorSymbol = " [";
307         Child2->Common.OperatorSymbol = "]";
308         break;
309 #endif
310
311     /* Unary operators */
312
313     case AML_DECREMENT_OP:
314         OperatorSymbol = "--";
315         break;
316
317     case AML_INCREMENT_OP:
318         OperatorSymbol = "++";
319         break;
320
321     case AML_BIT_NOT_OP:
322     case AML_STORE_OP:
323         OperatorSymbol = NULL;
324         break;
325
326     default:
327         return (FALSE);
328     }
329
330     if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
331     {
332         return (TRUE);
333     }
334
335     /*
336      * This is the key to how the disassembly of the C-style operators
337      * works. We save the operator symbol in the first child, thus
338      * deferring symbol output until after the first operand has been
339      * emitted.
340      */
341     if (!Child1->Common.OperatorSymbol)
342     {
343         Child1->Common.OperatorSymbol = OperatorSymbol;
344     }
345
346     /*
347      * Check for a valid target as the 3rd (or sometimes 2nd) operand
348      *
349      * Compound assignment operator support:
350      * Attempt to optimize constructs of the form:
351      *      Add (Local1, 0xFF, Local1)
352      * to:
353      *      Local1 += 0xFF
354      *
355      * Only the math operators and Store() have a target.
356      * Logicals have no target.
357      */
358     switch (Op->Common.AmlOpcode)
359     {
360     case AML_ADD_OP:
361     case AML_SUBTRACT_OP:
362     case AML_MULTIPLY_OP:
363     case AML_DIVIDE_OP:
364     case AML_MOD_OP:
365     case AML_SHIFT_LEFT_OP:
366     case AML_SHIFT_RIGHT_OP:
367     case AML_BIT_AND_OP:
368     case AML_BIT_OR_OP:
369     case AML_BIT_XOR_OP:
370
371         /* Target is 3rd operand */
372
373         Target = Child2->Common.Next;
374         if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
375         {
376             /*
377              * Divide has an extra target operand (Remainder).
378              * If this extra target is specified, it cannot be converted
379              * to a C-style operator
380              */
381             if (AcpiDmIsValidTarget (Target))
382             {
383                 Child1->Common.OperatorSymbol = NULL;
384                 return (FALSE);
385             }
386
387             Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
388             Target = Target->Common.Next;
389         }
390
391         /* Parser should ensure there is at least a placeholder target */
392
393         if (!Target)
394         {
395             return (FALSE);
396         }
397
398         if (!AcpiDmIsValidTarget (Target))
399         {
400             /* Not a valid target (placeholder only, from parser) */
401             break;
402         }
403
404         /*
405          * Promote the target up to the first child in the parse
406          * tree. This is done because the target will be output
407          * first, in the form:
408          *     <Target> = Operands...
409          */
410         AcpiDmPromoteTarget (Op, Target);
411
412         /*
413          * Check for possible conversion to a "Compound Assignment".
414          *
415          * Determine if either operand is the same as the target
416          * and display compound assignment operator and other operand.
417          */
418         if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
419             (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
420         {
421             Target->Common.OperatorSymbol =
422                 AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
423
424             /* Convert operator to compound assignment */
425
426             Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
427             Child1->Common.OperatorSymbol = NULL;
428             return (TRUE);
429         }
430
431         /*
432          * If we are within a C-style expression, emit an extra open
433          * paren. Implemented by examining the parent op.
434          */
435         switch (Op->Common.Parent->Common.AmlOpcode)
436         {
437         case AML_ADD_OP:
438         case AML_SUBTRACT_OP:
439         case AML_MULTIPLY_OP:
440         case AML_DIVIDE_OP:
441         case AML_MOD_OP:
442         case AML_SHIFT_LEFT_OP:
443         case AML_SHIFT_RIGHT_OP:
444         case AML_BIT_AND_OP:
445         case AML_BIT_OR_OP:
446         case AML_BIT_XOR_OP:
447         case AML_LAND_OP:
448         case AML_LEQUAL_OP:
449         case AML_LGREATER_OP:
450         case AML_LLESS_OP:
451         case AML_LOR_OP:
452
453             Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
454             AcpiOsPrintf ("(");
455             break;
456
457         default:
458             break;
459         }
460
461         /* Normal output for ASL/AML operators with a target operand */
462
463         Target->Common.OperatorSymbol = " = (";
464         return (TRUE);
465
466     /* Binary operators, no parens */
467
468     case AML_DECREMENT_OP:
469     case AML_INCREMENT_OP:
470         return (TRUE);
471
472 #ifdef INDEX_SUPPORT
473     case AML_INDEX_OP:
474
475         /* Target is optional, 3rd operand */
476
477         Target = Child2->Common.Next;
478         if (AcpiDmIsValidTarget (Target))
479         {
480             AcpiDmPromoteTarget (Op, Target);
481
482             if (!Target->Common.OperatorSymbol)
483             {
484                 Target->Common.OperatorSymbol = " = ";
485             }
486         }
487         return (TRUE);
488 #endif
489
490     case AML_STORE_OP:
491         /*
492          * Target is the 2nd operand.
493          * We know the target is valid, it is not optional.
494          * In the parse tree, simply swap the target with the
495          * source so that the target is processed first.
496          */
497         Target = Child1->Common.Next;
498         AcpiDmPromoteTarget (Op, Target);
499
500         if (!Target->Common.OperatorSymbol)
501         {
502             Target->Common.OperatorSymbol = " = ";
503         }
504         return (TRUE);
505
506     case AML_BIT_NOT_OP:
507
508         /* Target is optional, 2nd operand */
509
510         Target = Child1->Common.Next;
511         if (!Target)
512         {
513             return (FALSE);
514         }
515
516         if (AcpiDmIsValidTarget (Target))
517         {
518             /* Valid target, not a placeholder */
519
520             AcpiDmPromoteTarget (Op, Target);
521             Target->Common.OperatorSymbol = " = ~";
522         }
523         else
524         {
525             /* No target. Emit this prefix operator immediately */
526
527             AcpiOsPrintf ("~");
528         }
529         return (TRUE);
530
531     default:
532         break;
533     }
534
535     /* All other operators, emit an open paren */
536
537     AcpiOsPrintf ("(");
538     return (TRUE);
539 }
540
541
542 /*******************************************************************************
543  *
544  * FUNCTION:    AcpiDmCloseOperator
545  *
546  * PARAMETERS:  Op                  - Current parse object
547  *
548  * RETURN:      None
549  *
550  * DESCRIPTION: Closes an operator by adding a closing parentheses if and
551  *              when necessary. Called during ascending phase of the
552  *              parse tree walk.
553  *
554  ******************************************************************************/
555
556 void
557 AcpiDmCloseOperator (
558     ACPI_PARSE_OBJECT       *Op)
559 {
560
561     /* Always emit paren if ASL+ disassembly disabled */
562
563     if (!AcpiGbl_CstyleDisassembly)
564     {
565         AcpiOsPrintf (")");
566         return;
567     }
568
569     /* Check if we need to add an additional closing paren */
570
571     switch (Op->Common.AmlOpcode)
572     {
573     case AML_ADD_OP:
574     case AML_SUBTRACT_OP:
575     case AML_MULTIPLY_OP:
576     case AML_DIVIDE_OP:
577     case AML_MOD_OP:
578     case AML_SHIFT_LEFT_OP:
579     case AML_SHIFT_RIGHT_OP:
580     case AML_BIT_AND_OP:
581     case AML_BIT_OR_OP:
582     case AML_BIT_XOR_OP:
583     case AML_LAND_OP:
584     case AML_LEQUAL_OP:
585     case AML_LGREATER_OP:
586     case AML_LLESS_OP:
587     case AML_LOR_OP:
588
589         /* Emit paren only if this is not a compound assignment */
590
591         if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND)
592         {
593             return;
594         }
595
596         /* Emit extra close paren for assignment within an expression */
597
598         if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
599         {
600             AcpiOsPrintf (")");
601         }
602         break;
603
604
605     /* No need for parens for these */
606
607 #ifdef INDEX_SUPPORT
608     case AML_INDEX_OP:
609 #endif
610     case AML_DECREMENT_OP:
611     case AML_INCREMENT_OP:
612     case AML_LNOT_OP:
613     case AML_BIT_NOT_OP:
614     case AML_STORE_OP:
615         return;
616
617     default:
618
619         /* Always emit paren for non-ASL+ operators */
620         break;
621     }
622
623     AcpiOsPrintf (")");
624 }
625
626
627 /*******************************************************************************
628  *
629  * FUNCTION:    AcpiDmGetCompoundSymbol
630  *
631  * PARAMETERS:  AslOpcode
632  *
633  * RETURN:      String containing the compound assignment symbol
634  *
635  * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
636  *              return the appropriate operator string.
637  *
638  ******************************************************************************/
639
640 static char *
641 AcpiDmGetCompoundSymbol (
642    UINT16                   AmlOpcode)
643 {
644     char                    *Symbol;
645
646
647     switch (AmlOpcode)
648     {
649     case AML_ADD_OP:
650         Symbol = " += ";
651         break;
652
653     case AML_SUBTRACT_OP:
654         Symbol = " -= ";
655         break;
656
657     case AML_MULTIPLY_OP:
658         Symbol = " *= ";
659         break;
660
661     case AML_DIVIDE_OP:
662         Symbol = " /= ";
663         break;
664
665     case AML_MOD_OP:
666         Symbol = " %= ";
667         break;
668
669     case AML_SHIFT_LEFT_OP:
670         Symbol = " <<= ";
671         break;
672
673     case AML_SHIFT_RIGHT_OP:
674         Symbol = " >>= ";
675         break;
676
677     case AML_BIT_AND_OP:
678         Symbol = " &= ";
679         break;
680
681     case AML_BIT_OR_OP:
682         Symbol = " |= ";
683         break;
684
685     case AML_BIT_XOR_OP:
686         Symbol = " ^= ";
687         break;
688
689     default:
690
691         /* No operator string for all other opcodes */
692         return (NULL);
693     }
694
695     return (Symbol);
696 }
697
698
699 /*******************************************************************************
700  *
701  * FUNCTION:    AcpiDmPromoteTarget
702  *
703  * PARAMETERS:  Op                  - Operator parse object
704  *              Target              - Target associate with the Op
705  *
706  * RETURN:      None
707  *
708  * DESCRIPTION: Transform the parse tree by moving the target up to the first
709  *              child of the Op.
710  *
711  ******************************************************************************/
712
713 static void
714 AcpiDmPromoteTarget (
715     ACPI_PARSE_OBJECT       *Op,
716     ACPI_PARSE_OBJECT       *Target)
717 {
718     ACPI_PARSE_OBJECT       *Child;
719
720
721     /* Link target directly to the Op as first child */
722
723     Child = Op->Common.Value.Arg;
724     Op->Common.Value.Arg = Target;
725     Target->Common.Next = Child;
726
727     /* Find the last peer, it is linked to the target. Unlink it. */
728
729     while (Child->Common.Next != Target)
730     {
731         Child = Child->Common.Next;
732     }
733
734     Child->Common.Next = NULL;
735 }
736
737
738 /*******************************************************************************
739  *
740  * FUNCTION:    AcpiDmIsValidTarget
741  *
742  * PARAMETERS:  Target              - Target Op from the parse tree
743  *
744  * RETURN:      TRUE if the Target is real. FALSE if it is just a placeholder
745  *              Op that was inserted by the parser.
746  *
747  * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
748  *              In other words, determine if the optional target is used or
749  *              not.
750  *
751  ******************************************************************************/
752
753 static BOOLEAN
754 AcpiDmIsValidTarget (
755     ACPI_PARSE_OBJECT       *Target)
756 {
757
758     if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
759         (Target->Common.Value.Arg == NULL))
760     {
761         return (FALSE);
762     }
763
764     return (TRUE);
765 }
766
767
768 /*******************************************************************************
769  *
770  * FUNCTION:    AcpiDmIsTargetAnOperand
771  *
772  * PARAMETERS:  Target              - Target associated with the expression
773  *              Operand             - An operand associated with expression
774  *
775  * RETURN:      TRUE if expression can be converted to a compound assignment.
776  *              FALSE otherwise.
777  *
778  * DESCRIPTION: Determine if the Target duplicates the operand, in order to
779  *              detect if the expression can be converted to a compound
780  *              assigment. (+=, *=, etc.)
781  *
782  ******************************************************************************/
783
784 static BOOLEAN
785 AcpiDmIsTargetAnOperand (
786     ACPI_PARSE_OBJECT       *Target,
787     ACPI_PARSE_OBJECT       *Operand,
788     BOOLEAN                 TopLevel)
789 {
790     const ACPI_OPCODE_INFO  *OpInfo;
791     BOOLEAN                 Same;
792
793
794     /*
795      * Opcodes must match. Note: ignoring the difference between nameseg
796      * and namepath for now. May be needed later.
797      */
798     if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
799     {
800         return (FALSE);
801     }
802
803     /* Nodes should match, even if they are NULL */
804
805     if (Target->Common.Node != Operand->Common.Node)
806     {
807         return (FALSE);
808     }
809
810     /* Determine if a child exists */
811
812     OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
813     if (OpInfo->Flags & AML_HAS_ARGS)
814     {
815         Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
816             Operand->Common.Value.Arg, FALSE);
817         if (!Same)
818         {
819             return (FALSE);
820         }
821     }
822
823     /* Check the next peer, as long as we are not at the top level */
824
825     if ((!TopLevel) &&
826          Target->Common.Next)
827     {
828         Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
829             Operand->Common.Next, FALSE);
830         if (!Same)
831         {
832             return (FALSE);
833         }
834     }
835
836     /* Supress the duplicate operand at the top-level */
837
838     if (TopLevel)
839     {
840         Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
841     }
842     return (TRUE);
843 }
844
845 #endif