1 /*******************************************************************************
2  *
3  * Module Name: dmcstyle - Support for C-style operator disassembly
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpi.h"
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acdebug.h"
49 
50 #ifdef ACPI_DISASSEMBLER
51 
52 #define _COMPONENT          ACPI_CA_DEBUGGER
53         ACPI_MODULE_NAME    ("dmcstyle")
54 
55 
56 /* Local prototypes */
57 
58 static char *
59 AcpiDmGetCompoundSymbol (
60    UINT16                   AslOpcode);
61 
62 static void
63 AcpiDmPromoteTarget (
64     ACPI_PARSE_OBJECT       *Op,
65     ACPI_PARSE_OBJECT       *Target);
66 
67 static BOOLEAN
68 AcpiDmIsValidTarget (
69     ACPI_PARSE_OBJECT       *Op);
70 
71 static BOOLEAN
72 AcpiDmIsTargetAnOperand (
73     ACPI_PARSE_OBJECT       *Target,
74     ACPI_PARSE_OBJECT       *Operand,
75     BOOLEAN                 TopLevel);
76 
77 
78 /*******************************************************************************
79  *
80  * FUNCTION:    AcpiDmCheckForSymbolicOpcode
81  *
82  * PARAMETERS:  Op                  - Current parse object
83  *              Walk                - Current parse tree walk info
84  *
85  * RETURN:      TRUE if opcode can be converted to symbolic, FALSE otherwise
86  *
87  * DESCRIPTION: This is the main code that implements disassembly of AML code
88  *              to C-style operators. Called during descending phase of the
89  *              parse tree walk.
90  *
91  ******************************************************************************/
92 
93 BOOLEAN
94 AcpiDmCheckForSymbolicOpcode (
95     ACPI_PARSE_OBJECT       *Op,
96     ACPI_OP_WALK_INFO       *Info)
97 {
98     char                    *OperatorSymbol = NULL;
99     ACPI_PARSE_OBJECT       *Child1;
100     ACPI_PARSE_OBJECT       *Child2;
101     ACPI_PARSE_OBJECT       *Target;
102 
103 
104     /* Exit immediately if ASL+ not enabled */
105 
106     if (!AcpiGbl_CstyleDisassembly)
107     {
108         return (FALSE);
109     }
110 
111     /* Get the first operand */
112 
113     Child1 = AcpiPsGetArg (Op, 0);
114     if (!Child1)
115     {
116         return (FALSE);
117     }
118 
119     /* Get the second operand */
120 
121     Child2 = Child1->Common.Next;
122 
123     /* Setup the operator string for this opcode */
124 
125     switch (Op->Common.AmlOpcode)
126     {
127     case AML_ADD_OP:
128         OperatorSymbol = " + ";
129         break;
130 
131     case AML_SUBTRACT_OP:
132         OperatorSymbol = " - ";
133         break;
134 
135     case AML_MULTIPLY_OP:
136         OperatorSymbol = " * ";
137         break;
138 
139     case AML_DIVIDE_OP:
140         OperatorSymbol = " / ";
141         break;
142 
143     case AML_MOD_OP:
144         OperatorSymbol = " % ";
145         break;
146 
147     case AML_SHIFT_LEFT_OP:
148         OperatorSymbol = " << ";
149         break;
150 
151     case AML_SHIFT_RIGHT_OP:
152         OperatorSymbol = " >> ";
153         break;
154 
155     case AML_BIT_AND_OP:
156         OperatorSymbol = " & ";
157         break;
158 
159     case AML_BIT_OR_OP:
160         OperatorSymbol = " | ";
161         break;
162 
163     case AML_BIT_XOR_OP:
164         OperatorSymbol = " ^ ";
165         break;
166 
167     /* Logical operators, no target */
168 
169     case AML_LAND_OP:
170         OperatorSymbol = " && ";
171         break;
172 
173     case AML_LEQUAL_OP:
174         OperatorSymbol = " == ";
175         break;
176 
177     case AML_LGREATER_OP:
178         OperatorSymbol = " > ";
179         break;
180 
181     case AML_LLESS_OP:
182         OperatorSymbol = " < ";
183         break;
184 
185     case AML_LOR_OP:
186         OperatorSymbol = " || ";
187         break;
188 
189     case AML_LNOT_OP:
190         /*
191          * Check for the LNOT sub-opcodes. These correspond to
192          * LNotEqual, LLessEqual, and LGreaterEqual. There are
193          * no actual AML opcodes for these operators.
194          */
195         switch (Child1->Common.AmlOpcode)
196         {
197         case AML_LEQUAL_OP:
198             OperatorSymbol = " != ";
199             break;
200 
201         case AML_LGREATER_OP:
202             OperatorSymbol = " <= ";
203             break;
204 
205         case AML_LLESS_OP:
206             OperatorSymbol = " >= ";
207             break;
208 
209         default:
210 
211             /* Unary LNOT case, emit "!" immediately */
212 
213             AcpiOsPrintf ("!");
214             return (TRUE);
215         }
216 
217         Child1->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
218         Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
219 
220         /* Save symbol string in the next child (not peer) */
221 
222         Child2 = AcpiPsGetArg (Child1, 0);
223         if (!Child2)
224         {
225             return (FALSE);
226         }
227 
228         Child2->Common.OperatorSymbol = OperatorSymbol;
229         return (TRUE);
230 
231 #ifdef INDEX_SUPPORT
232     case AML_INDEX_OP:
233         Child1->Common.OperatorSymbol = " [";
234         Child2->Common.OperatorSymbol = "]";
235         break;
236 #endif
237 
238     /* Unary operators */
239 
240     case AML_DECREMENT_OP:
241         OperatorSymbol = "--";
242         break;
243 
244     case AML_INCREMENT_OP:
245         OperatorSymbol = "++";
246         break;
247 
248     case AML_BIT_NOT_OP:
249     case AML_STORE_OP:
250         OperatorSymbol = NULL;
251         break;
252 
253     default:
254         return (FALSE);
255     }
256 
257     if (Child1->Common.DisasmOpcode == ACPI_DASM_LNOT_SUFFIX)
258     {
259         return (TRUE);
260     }
261 
262     /*
263      * This is the key to how the disassembly of the C-style operators
264      * works. We save the operator symbol in the first child, thus
265      * deferring symbol output until after the first operand has been
266      * emitted.
267      */
268     if (!Child1->Common.OperatorSymbol)
269     {
270         Child1->Common.OperatorSymbol = OperatorSymbol;
271     }
272 
273     /*
274      * Check for a valid target as the 3rd (or sometimes 2nd) operand
275      *
276      * Compound assignment operator support:
277      * Attempt to optimize constructs of the form:
278      *      Add (Local1, 0xFF, Local1)
279      * to:
280      *      Local1 += 0xFF
281      *
282      * Only the math operators and Store() have a target.
283      * Logicals have no target.
284      */
285     switch (Op->Common.AmlOpcode)
286     {
287     case AML_ADD_OP:
288     case AML_SUBTRACT_OP:
289     case AML_MULTIPLY_OP:
290     case AML_DIVIDE_OP:
291     case AML_MOD_OP:
292     case AML_SHIFT_LEFT_OP:
293     case AML_SHIFT_RIGHT_OP:
294     case AML_BIT_AND_OP:
295     case AML_BIT_OR_OP:
296     case AML_BIT_XOR_OP:
297 
298         /* Target is 3rd operand */
299 
300         Target = Child2->Common.Next;
301         if (Op->Common.AmlOpcode == AML_DIVIDE_OP)
302         {
303             /*
304              * Divide has an extra target operand (Remainder).
305              * If this extra target is specified, it cannot be converted
306              * to a C-style operator
307              */
308             if (AcpiDmIsValidTarget (Target))
309             {
310                 Child1->Common.OperatorSymbol = NULL;
311                 return (FALSE);
312             }
313 
314             Target->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
315             Target = Target->Common.Next;
316         }
317 
318         /* Parser should ensure there is at least a placeholder target */
319 
320         if (!Target)
321         {
322             return (FALSE);
323         }
324 
325         if (!AcpiDmIsValidTarget (Target))
326         {
327             /* Not a valid target (placeholder only, from parser) */
328             break;
329         }
330 
331         /*
332          * Promote the target up to the first child in the parse
333          * tree. This is done because the target will be output
334          * first, in the form:
335          *     <Target> = Operands...
336          */
337         AcpiDmPromoteTarget (Op, Target);
338 
339         /* Check operands for conversion to a "Compound Assignment" */
340 
341         switch (Op->Common.AmlOpcode)
342         {
343             /* Commutative operators */
344 
345         case AML_ADD_OP:
346         case AML_MULTIPLY_OP:
347         case AML_BIT_AND_OP:
348         case AML_BIT_OR_OP:
349         case AML_BIT_XOR_OP:
350             /*
351              * For the commutative operators, we can convert to a
352              * compound statement only if at least one (either) operand
353              * is the same as the target.
354              *
355              *      Add (A, B, A) --> A += B
356              *      Add (B, A, A) --> A += B
357              *      Add (B, C, A) --> A = (B + C)
358              */
359             if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
360                 (AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
361             {
362                 Target->Common.OperatorSymbol =
363                     AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
364 
365                 /* Convert operator to compound assignment */
366 
367                 Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
368                 Child1->Common.OperatorSymbol = NULL;
369                 return (TRUE);
370             }
371             break;
372 
373             /* Non-commutative operators */
374 
375         case AML_SUBTRACT_OP:
376         case AML_DIVIDE_OP:
377         case AML_MOD_OP:
378         case AML_SHIFT_LEFT_OP:
379         case AML_SHIFT_RIGHT_OP:
380             /*
381              * For the non-commutative operators, we can convert to a
382              * compound statement only if the target is the same as the
383              * first operand.
384              *
385              *      Subtract (A, B, A) --> A -= B
386              *      Subtract (B, A, A) --> A = (B - A)
387              */
388             if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)))
389             {
390                 Target->Common.OperatorSymbol =
391                     AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
392 
393                 /* Convert operator to compound assignment */
394 
395                 Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
396                 Child1->Common.OperatorSymbol = NULL;
397                 return (TRUE);
398             }
399             break;
400 
401         default:
402             break;
403         }
404 
405         /*
406          * If we are within a C-style expression, emit an extra open
407          * paren. Implemented by examining the parent op.
408          */
409         switch (Op->Common.Parent->Common.AmlOpcode)
410         {
411         case AML_ADD_OP:
412         case AML_SUBTRACT_OP:
413         case AML_MULTIPLY_OP:
414         case AML_DIVIDE_OP:
415         case AML_MOD_OP:
416         case AML_SHIFT_LEFT_OP:
417         case AML_SHIFT_RIGHT_OP:
418         case AML_BIT_AND_OP:
419         case AML_BIT_OR_OP:
420         case AML_BIT_XOR_OP:
421         case AML_LAND_OP:
422         case AML_LEQUAL_OP:
423         case AML_LGREATER_OP:
424         case AML_LLESS_OP:
425         case AML_LOR_OP:
426 
427             Op->Common.DisasmFlags |= ACPI_PARSEOP_ASSIGNMENT;
428             AcpiOsPrintf ("(");
429             break;
430 
431         default:
432             break;
433         }
434 
435         /* Normal output for ASL/AML operators with a target operand */
436 
437         Target->Common.OperatorSymbol = " = (";
438         return (TRUE);
439 
440     /* Binary operators, no parens */
441 
442     case AML_DECREMENT_OP:
443     case AML_INCREMENT_OP:
444         return (TRUE);
445 
446 #ifdef INDEX_SUPPORT
447     case AML_INDEX_OP:
448 
449         /* Target is optional, 3rd operand */
450 
451         Target = Child2->Common.Next;
452         if (AcpiDmIsValidTarget (Target))
453         {
454             AcpiDmPromoteTarget (Op, Target);
455 
456             if (!Target->Common.OperatorSymbol)
457             {
458                 Target->Common.OperatorSymbol = " = ";
459             }
460         }
461         return (TRUE);
462 #endif
463 
464     case AML_STORE_OP:
465         /*
466          * Target is the 2nd operand.
467          * We know the target is valid, it is not optional.
468          * In the parse tree, simply swap the target with the
469          * source so that the target is processed first.
470          */
471         Target = Child1->Common.Next;
472         if (!Target)
473         {
474             return (FALSE);
475         }
476 
477         AcpiDmPromoteTarget (Op, Target);
478         if (!Target->Common.OperatorSymbol)
479         {
480             Target->Common.OperatorSymbol = " = ";
481         }
482         return (TRUE);
483 
484     case AML_BIT_NOT_OP:
485 
486         /* Target is optional, 2nd operand */
487 
488         Target = Child1->Common.Next;
489         if (!Target)
490         {
491             return (FALSE);
492         }
493 
494         if (AcpiDmIsValidTarget (Target))
495         {
496             /* Valid target, not a placeholder */
497 
498             AcpiDmPromoteTarget (Op, Target);
499             Target->Common.OperatorSymbol = " = ~";
500         }
501         else
502         {
503             /* No target. Emit this prefix operator immediately */
504 
505             AcpiOsPrintf ("~");
506         }
507         return (TRUE);
508 
509     default:
510         break;
511     }
512 
513     /* All other operators, emit an open paren */
514 
515     AcpiOsPrintf ("(");
516     return (TRUE);
517 }
518 
519 
520 /*******************************************************************************
521  *
522  * FUNCTION:    AcpiDmCloseOperator
523  *
524  * PARAMETERS:  Op                  - Current parse object
525  *
526  * RETURN:      None
527  *
528  * DESCRIPTION: Closes an operator by adding a closing parentheses if and
529  *              when necessary. Called during ascending phase of the
530  *              parse tree walk.
531  *
532  ******************************************************************************/
533 
534 void
535 AcpiDmCloseOperator (
536     ACPI_PARSE_OBJECT       *Op)
537 {
538 
539     /* Always emit paren if ASL+ disassembly disabled */
540 
541     if (!AcpiGbl_CstyleDisassembly)
542     {
543         AcpiOsPrintf (")");
544         return;
545     }
546 
547     /* Check if we need to add an additional closing paren */
548 
549     switch (Op->Common.AmlOpcode)
550     {
551     case AML_ADD_OP:
552     case AML_SUBTRACT_OP:
553     case AML_MULTIPLY_OP:
554     case AML_DIVIDE_OP:
555     case AML_MOD_OP:
556     case AML_SHIFT_LEFT_OP:
557     case AML_SHIFT_RIGHT_OP:
558     case AML_BIT_AND_OP:
559     case AML_BIT_OR_OP:
560     case AML_BIT_XOR_OP:
561     case AML_LAND_OP:
562     case AML_LEQUAL_OP:
563     case AML_LGREATER_OP:
564     case AML_LLESS_OP:
565     case AML_LOR_OP:
566 
567         /* Emit paren only if this is not a compound assignment */
568 
569         if (Op->Common.DisasmFlags & ACPI_PARSEOP_COMPOUND)
570         {
571             return;
572         }
573 
574         /* Emit extra close paren for assignment within an expression */
575 
576         if (Op->Common.DisasmFlags & ACPI_PARSEOP_ASSIGNMENT)
577         {
578             AcpiOsPrintf (")");
579         }
580         break;
581 
582 
583     /* No need for parens for these */
584 
585 #ifdef INDEX_SUPPORT
586     case AML_INDEX_OP:
587 #endif
588     case AML_DECREMENT_OP:
589     case AML_INCREMENT_OP:
590     case AML_LNOT_OP:
591     case AML_BIT_NOT_OP:
592     case AML_STORE_OP:
593         return;
594 
595     default:
596 
597         /* Always emit paren for non-ASL+ operators */
598         break;
599     }
600 
601     AcpiOsPrintf (")");
602 }
603 
604 
605 /*******************************************************************************
606  *
607  * FUNCTION:    AcpiDmGetCompoundSymbol
608  *
609  * PARAMETERS:  AslOpcode
610  *
611  * RETURN:      String containing the compound assignment symbol
612  *
613  * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
614  *              return the appropriate operator string.
615  *
616  ******************************************************************************/
617 
618 static char *
619 AcpiDmGetCompoundSymbol (
620    UINT16                   AmlOpcode)
621 {
622     char                    *Symbol;
623 
624 
625     switch (AmlOpcode)
626     {
627     case AML_ADD_OP:
628         Symbol = " += ";
629         break;
630 
631     case AML_SUBTRACT_OP:
632         Symbol = " -= ";
633         break;
634 
635     case AML_MULTIPLY_OP:
636         Symbol = " *= ";
637         break;
638 
639     case AML_DIVIDE_OP:
640         Symbol = " /= ";
641         break;
642 
643     case AML_MOD_OP:
644         Symbol = " %= ";
645         break;
646 
647     case AML_SHIFT_LEFT_OP:
648         Symbol = " <<= ";
649         break;
650 
651     case AML_SHIFT_RIGHT_OP:
652         Symbol = " >>= ";
653         break;
654 
655     case AML_BIT_AND_OP:
656         Symbol = " &= ";
657         break;
658 
659     case AML_BIT_OR_OP:
660         Symbol = " |= ";
661         break;
662 
663     case AML_BIT_XOR_OP:
664         Symbol = " ^= ";
665         break;
666 
667     default:
668 
669         /* No operator string for all other opcodes */
670         return (NULL);
671     }
672 
673     return (Symbol);
674 }
675 
676 
677 /*******************************************************************************
678  *
679  * FUNCTION:    AcpiDmPromoteTarget
680  *
681  * PARAMETERS:  Op                  - Operator parse object
682  *              Target              - Target associate with the Op
683  *
684  * RETURN:      None
685  *
686  * DESCRIPTION: Transform the parse tree by moving the target up to the first
687  *              child of the Op.
688  *
689  ******************************************************************************/
690 
691 static void
692 AcpiDmPromoteTarget (
693     ACPI_PARSE_OBJECT       *Op,
694     ACPI_PARSE_OBJECT       *Target)
695 {
696     ACPI_PARSE_OBJECT       *Child;
697 
698 
699     /* Link target directly to the Op as first child */
700 
701     Child = Op->Common.Value.Arg;
702     Op->Common.Value.Arg = Target;
703     Target->Common.Next = Child;
704 
705     /* Find the last peer, it is linked to the target. Unlink it. */
706 
707     while (Child->Common.Next != Target)
708     {
709         Child = Child->Common.Next;
710     }
711 
712     Child->Common.Next = NULL;
713 }
714 
715 
716 /*******************************************************************************
717  *
718  * FUNCTION:    AcpiDmIsValidTarget
719  *
720  * PARAMETERS:  Target              - Target Op from the parse tree
721  *
722  * RETURN:      TRUE if the Target is real. FALSE if it is just a placeholder
723  *              Op that was inserted by the parser.
724  *
725  * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
726  *              In other words, determine if the optional target is used or
727  *              not. Note: If Target is NULL, something is seriously wrong,
728  *              probably with the parse tree.
729  *
730  ******************************************************************************/
731 
732 static BOOLEAN
733 AcpiDmIsValidTarget (
734     ACPI_PARSE_OBJECT       *Target)
735 {
736 
737     if (!Target)
738     {
739         return (FALSE);
740     }
741 
742     if ((Target->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
743         (Target->Common.Value.Arg == NULL))
744     {
745         return (FALSE);
746     }
747 
748     return (TRUE);
749 }
750 
751 
752 /*******************************************************************************
753  *
754  * FUNCTION:    AcpiDmIsTargetAnOperand
755  *
756  * PARAMETERS:  Target              - Target associated with the expression
757  *              Operand             - An operand associated with expression
758  *
759  * RETURN:      TRUE if expression can be converted to a compound assignment.
760  *              FALSE otherwise.
761  *
762  * DESCRIPTION: Determine if the Target duplicates the operand, in order to
763  *              detect if the expression can be converted to a compound
764  *              assigment. (+=, *=, etc.)
765  *
766  ******************************************************************************/
767 
768 static BOOLEAN
769 AcpiDmIsTargetAnOperand (
770     ACPI_PARSE_OBJECT       *Target,
771     ACPI_PARSE_OBJECT       *Operand,
772     BOOLEAN                 TopLevel)
773 {
774     const ACPI_OPCODE_INFO  *OpInfo;
775     BOOLEAN                 Same;
776 
777 
778     /*
779      * Opcodes must match. Note: ignoring the difference between nameseg
780      * and namepath for now. May be needed later.
781      */
782     if (Target->Common.AmlOpcode != Operand->Common.AmlOpcode)
783     {
784         return (FALSE);
785     }
786 
787     /* Nodes should match, even if they are NULL */
788 
789     if (Target->Common.Node != Operand->Common.Node)
790     {
791         return (FALSE);
792     }
793 
794     /* Determine if a child exists */
795 
796     OpInfo = AcpiPsGetOpcodeInfo (Operand->Common.AmlOpcode);
797     if (OpInfo->Flags & AML_HAS_ARGS)
798     {
799         Same = AcpiDmIsTargetAnOperand (Target->Common.Value.Arg,
800             Operand->Common.Value.Arg, FALSE);
801         if (!Same)
802         {
803             return (FALSE);
804         }
805     }
806 
807     /* Check the next peer, as long as we are not at the top level */
808 
809     if ((!TopLevel) &&
810          Target->Common.Next)
811     {
812         Same = AcpiDmIsTargetAnOperand (Target->Common.Next,
813             Operand->Common.Next, FALSE);
814         if (!Same)
815         {
816             return (FALSE);
817         }
818     }
819 
820     /* Supress the duplicate operand at the top-level */
821 
822     if (TopLevel)
823     {
824         Operand->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
825     }
826     return (TRUE);
827 }
828 
829 #endif
830