1 /*******************************************************************************
3 * Module Name: dmcstyle - Support for C-style operator disassembly
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2017, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
49 #include "acconvert.h"
51 #ifdef ACPI_DISASSEMBLER
53 #define _COMPONENT ACPI_CA_DEBUGGER
54 ACPI_MODULE_NAME ("dmcstyle")
57 /* Local prototypes */
60 AcpiDmGetCompoundSymbol (
65 ACPI_PARSE_OBJECT
*Op
,
66 ACPI_PARSE_OBJECT
*Target
);
70 ACPI_PARSE_OBJECT
*Op
);
73 AcpiDmIsTargetAnOperand (
74 ACPI_PARSE_OBJECT
*Target
,
75 ACPI_PARSE_OBJECT
*Operand
,
79 AcpiDmIsOptimizationIgnored (
80 ACPI_PARSE_OBJECT
*StoreOp
,
81 ACPI_PARSE_OBJECT
*StoreArgument
);
84 /*******************************************************************************
86 * FUNCTION: AcpiDmCheckForSymbolicOpcode
88 * PARAMETERS: Op - Current parse object
89 * Walk - Current parse tree walk info
91 * RETURN: TRUE if opcode can be converted to symbolic, FALSE otherwise
93 * DESCRIPTION: This is the main code that implements disassembly of AML code
94 * to C-style operators. Called during descending phase of the
97 ******************************************************************************/
100 AcpiDmCheckForSymbolicOpcode (
101 ACPI_PARSE_OBJECT
*Op
,
102 ACPI_OP_WALK_INFO
*Info
)
104 char *OperatorSymbol
= NULL
;
105 ACPI_PARSE_OBJECT
*Argument1
;
106 ACPI_PARSE_OBJECT
*Argument2
;
107 ACPI_PARSE_OBJECT
*Target
;
108 ACPI_PARSE_OBJECT
*Target2
;
111 /* Exit immediately if ASL+ not enabled */
113 if (!AcpiGbl_CstyleDisassembly
)
118 /* Get the first operand */
120 Argument1
= AcpiPsGetArg (Op
, 0);
126 /* Get the second operand */
128 Argument2
= Argument1
->Common
.Next
;
130 /* Setup the operator string for this opcode */
132 switch (Op
->Common
.AmlOpcode
)
135 OperatorSymbol
= " + ";
138 case AML_SUBTRACT_OP
:
139 OperatorSymbol
= " - ";
142 case AML_MULTIPLY_OP
:
143 OperatorSymbol
= " * ";
147 OperatorSymbol
= " / ";
151 OperatorSymbol
= " % ";
154 case AML_SHIFT_LEFT_OP
:
155 OperatorSymbol
= " << ";
158 case AML_SHIFT_RIGHT_OP
:
159 OperatorSymbol
= " >> ";
163 OperatorSymbol
= " & ";
167 OperatorSymbol
= " | ";
171 OperatorSymbol
= " ^ ";
174 /* Logical operators, no target */
176 case AML_LOGICAL_AND_OP
:
177 OperatorSymbol
= " && ";
180 case AML_LOGICAL_EQUAL_OP
:
181 OperatorSymbol
= " == ";
184 case AML_LOGICAL_GREATER_OP
:
185 OperatorSymbol
= " > ";
188 case AML_LOGICAL_LESS_OP
:
189 OperatorSymbol
= " < ";
192 case AML_LOGICAL_OR_OP
:
193 OperatorSymbol
= " || ";
196 case AML_LOGICAL_NOT_OP
:
198 * Check for the LNOT sub-opcodes. These correspond to
199 * LNotEqual, LLessEqual, and LGreaterEqual. There are
200 * no actual AML opcodes for these operators.
202 switch (Argument1
->Common
.AmlOpcode
)
204 case AML_LOGICAL_EQUAL_OP
:
205 OperatorSymbol
= " != ";
208 case AML_LOGICAL_GREATER_OP
:
209 OperatorSymbol
= " <= ";
212 case AML_LOGICAL_LESS_OP
:
213 OperatorSymbol
= " >= ";
218 /* Unary LNOT case, emit "!" immediately */
224 Argument1
->Common
.DisasmOpcode
= ACPI_DASM_LNOT_SUFFIX
;
225 Op
->Common
.DisasmOpcode
= ACPI_DASM_LNOT_PREFIX
;
227 /* Save symbol string in the next child (not peer) */
229 Argument2
= AcpiPsGetArg (Argument1
, 0);
235 Argument2
->Common
.OperatorSymbol
= OperatorSymbol
;
240 * Check for constant source operand. Note: although technically
241 * legal syntax, the iASL compiler does not support this with
242 * the symbolic operators for Index(). It doesn't make sense to
243 * use Index() with a constant anyway.
245 if ((Argument1
->Common
.AmlOpcode
== AML_STRING_OP
) ||
246 (Argument1
->Common
.AmlOpcode
== AML_BUFFER_OP
) ||
247 (Argument1
->Common
.AmlOpcode
== AML_PACKAGE_OP
) ||
248 (Argument1
->Common
.AmlOpcode
== AML_VARIABLE_PACKAGE_OP
))
250 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_CLOSING_PAREN
;
254 /* Index operator is [] */
256 Argument1
->Common
.OperatorSymbol
= " [";
257 Argument2
->Common
.OperatorSymbol
= "]";
260 /* Unary operators */
262 case AML_DECREMENT_OP
:
263 OperatorSymbol
= "--";
266 case AML_INCREMENT_OP
:
267 OperatorSymbol
= "++";
272 OperatorSymbol
= NULL
;
279 if (Argument1
->Common
.DisasmOpcode
== ACPI_DASM_LNOT_SUFFIX
)
285 * This is the key to how the disassembly of the C-style operators
286 * works. We save the operator symbol in the first child, thus
287 * deferring symbol output until after the first operand has been
290 if (!Argument1
->Common
.OperatorSymbol
)
292 Argument1
->Common
.OperatorSymbol
= OperatorSymbol
;
296 * Check for a valid target as the 3rd (or sometimes 2nd) operand
298 * Compound assignment operator support:
299 * Attempt to optimize constructs of the form:
300 * Add (Local1, 0xFF, Local1)
304 * Only the math operators and Store() have a target.
305 * Logicals have no target.
307 switch (Op
->Common
.AmlOpcode
)
310 case AML_SUBTRACT_OP
:
311 case AML_MULTIPLY_OP
:
314 case AML_SHIFT_LEFT_OP
:
315 case AML_SHIFT_RIGHT_OP
:
320 /* Target is 3rd operand */
322 Target
= Argument2
->Common
.Next
;
323 if (Op
->Common
.AmlOpcode
== AML_DIVIDE_OP
)
325 Target2
= Target
->Common
.Next
;
328 * Divide has an extra target operand (Remainder).
329 * Default behavior is to simply ignore ASL+ conversion
330 * if the remainder target (modulo) is specified.
332 if (!AcpiGbl_DoDisassemblerOptimizations
)
334 if (AcpiDmIsValidTarget (Target
))
336 Argument1
->Common
.OperatorSymbol
= NULL
;
337 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_LEGACY_ASL_ONLY
;
341 Target
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
347 * Divide has an extra target operand (Remainder).
348 * If both targets are specified, it cannot be converted
349 * to a C-style operator.
351 if (AcpiDmIsValidTarget (Target
) &&
352 AcpiDmIsValidTarget (Target2
))
354 Argument1
->Common
.OperatorSymbol
= NULL
;
355 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_LEGACY_ASL_ONLY
;
359 if (AcpiDmIsValidTarget (Target
)) /* Only first Target is valid (remainder) */
361 /* Convert the Divide to Modulo */
363 Op
->Common
.AmlOpcode
= AML_MOD_OP
;
365 Argument1
->Common
.OperatorSymbol
= " % ";
366 Target2
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
368 else /* Only second Target (quotient) is valid */
370 Target
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;
376 /* Parser should ensure there is at least a placeholder target */
383 if (!AcpiDmIsValidTarget (Target
))
385 /* Not a valid target (placeholder only, from parser) */
390 * Promote the target up to the first child in the parse
391 * tree. This is done because the target will be output
392 * first, in the form:
393 * <Target> = Operands...
395 AcpiDmPromoteTarget (Op
, Target
);
397 /* Check operands for conversion to a "Compound Assignment" */
399 switch (Op
->Common
.AmlOpcode
)
401 /* Commutative operators */
404 case AML_MULTIPLY_OP
:
409 * For the commutative operators, we can convert to a
410 * compound statement only if at least one (either) operand
411 * is the same as the target.
413 * Add (A, B, A) --> A += B
414 * Add (B, A, A) --> A += B
415 * Add (B, C, A) --> A = (B + C)
417 if ((AcpiDmIsTargetAnOperand (Target
, Argument1
, TRUE
)) ||
418 (AcpiDmIsTargetAnOperand (Target
, Argument2
, TRUE
)))
420 Target
->Common
.OperatorSymbol
=
421 AcpiDmGetCompoundSymbol (Op
->Common
.AmlOpcode
);
423 /* Convert operator to compound assignment */
425 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_COMPOUND_ASSIGNMENT
;
426 Argument1
->Common
.OperatorSymbol
= NULL
;
431 /* Non-commutative operators */
433 case AML_SUBTRACT_OP
:
436 case AML_SHIFT_LEFT_OP
:
437 case AML_SHIFT_RIGHT_OP
:
439 * For the non-commutative operators, we can convert to a
440 * compound statement only if the target is the same as the
443 * Subtract (A, B, A) --> A -= B
444 * Subtract (B, A, A) --> A = (B - A)
446 if ((AcpiDmIsTargetAnOperand (Target
, Argument1
, TRUE
)))
448 Target
->Common
.OperatorSymbol
=
449 AcpiDmGetCompoundSymbol (Op
->Common
.AmlOpcode
);
451 /* Convert operator to compound assignment */
453 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_COMPOUND_ASSIGNMENT
;
454 Argument1
->Common
.OperatorSymbol
= NULL
;
464 * If we are within a C-style expression, emit an extra open
465 * paren. Implemented by examining the parent op.
467 switch (Op
->Common
.Parent
->Common
.AmlOpcode
)
470 case AML_SUBTRACT_OP
:
471 case AML_MULTIPLY_OP
:
474 case AML_SHIFT_LEFT_OP
:
475 case AML_SHIFT_RIGHT_OP
:
479 case AML_LOGICAL_AND_OP
:
480 case AML_LOGICAL_EQUAL_OP
:
481 case AML_LOGICAL_GREATER_OP
:
482 case AML_LOGICAL_LESS_OP
:
483 case AML_LOGICAL_OR_OP
:
485 Op
->Common
.DisasmFlags
|= ACPI_PARSEOP_ASSIGNMENT
;
493 /* Normal output for ASL/AML operators with a target operand */
495 Target
->Common
.OperatorSymbol
= " = (";
498 /* Binary operators, no parens */
500 case AML_DECREMENT_OP
:
501 case AML_INCREMENT_OP
:
506 /* Target is optional, 3rd operand */
508 Target
= Argument2
->Common
.Next
;
509 if (AcpiDmIsValidTarget (Target
))
511 AcpiDmPromoteTarget (Op
, Target
);
513 if (!Target
->Common
.OperatorSymbol
)
515 Target
->Common
.OperatorSymbol
= " = ";
522 * For Store, the Target is the 2nd operand. We know the target
523 * is valid, because it is not optional.
525 * Ignore any optimizations/folding if flag is set.
526 * Used for iASL/disassembler test suite only.
528 if (AcpiDmIsOptimizationIgnored (Op
, Argument1
))
534 * Perform conversion.
535 * In the parse tree, simply swap the target with the
536 * source so that the target is processed first.
538 Target
= Argument1
->Common
.Next
;
544 AcpiDmPromoteTarget (Op
, Target
);
545 if (!Target
->Common
.OperatorSymbol
)
547 Target
->Common
.OperatorSymbol
= " = ";
553 /* Target is optional, 2nd operand */
555 Target
= Argument1
->Common
.Next
;
561 if (AcpiDmIsValidTarget (Target
))
563 /* Valid target, not a placeholder */
565 AcpiDmPromoteTarget (Op
, Target
);
566 Target
->Common
.OperatorSymbol
= " = ~";
570 /* No target. Emit this prefix operator immediately */
580 /* All other operators, emit an open paren */
587 /*******************************************************************************
589 * FUNCTION: AcpiDmIsOptimizationIgnored
591 * PARAMETERS: StoreOp - Store operator parse object
592 * StoreArgument - Target associate with the Op
594 * RETURN: TRUE if this Store operator should not be converted/removed.
596 * DESCRIPTION: The following function implements "Do not optimize if a
597 * store is immediately followed by a math/bit operator that
600 * Function is ignored if DoDisassemblerOptimizations is TRUE.
601 * This is the default, ignore this function.
603 * Disables these types of optimizations, and simply emits
605 * Store (Add (INT1, 4), INT2) --> Add (INT1, 4, INT2)
606 * --> INT2 = INT1 + 4
608 * Store (Not (INT1), INT2) --> Not (INT1, INT2)
611 * Used only for the ASL test suite. For the test suite, we
612 * don't want to perform some optimizations to ensure binary
613 * compatibility with the generation of the legacy ASL->AML.
614 * In other words, for all test modules we want exactly:
615 * (ASL+ -> AML) == (ASL- -> AML)
617 ******************************************************************************/
620 AcpiDmIsOptimizationIgnored (
621 ACPI_PARSE_OBJECT
*StoreOp
,
622 ACPI_PARSE_OBJECT
*StoreArgument
)
624 ACPI_PARSE_OBJECT
*Argument1
;
625 ACPI_PARSE_OBJECT
*Argument2
;
626 ACPI_PARSE_OBJECT
*Target
;
629 /* No optimizations/folding for the typical case */
631 if (AcpiGbl_DoDisassemblerOptimizations
)
637 * Only a small subset of ASL/AML operators can be optimized.
638 * Can only optimize/fold if there is no target (or targets)
639 * specified for the operator. And of course, the operator
640 * is surrrounded by a Store() operator.
642 switch (StoreArgument
->Common
.AmlOpcode
)
645 case AML_SUBTRACT_OP
:
646 case AML_MULTIPLY_OP
:
648 case AML_SHIFT_LEFT_OP
:
649 case AML_SHIFT_RIGHT_OP
:
655 /* These operators have two arguments and one target */
657 Argument1
= StoreArgument
->Common
.Value
.Arg
;
658 Argument2
= Argument1
->Common
.Next
;
659 Target
= Argument2
->Common
.Next
;
661 if (!AcpiDmIsValidTarget (Target
))
663 StoreOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_LEGACY_ASL_ONLY
;
670 /* This operator has two arguments and two targets */
672 Argument1
= StoreArgument
->Common
.Value
.Arg
;
673 Argument2
= Argument1
->Common
.Next
;
674 Target
= Argument2
->Common
.Next
;
676 if (!AcpiDmIsValidTarget (Target
) ||
677 !AcpiDmIsValidTarget (Target
->Common
.Next
))
679 StoreOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_LEGACY_ASL_ONLY
;
686 /* This operator has one operand and one target */
688 Argument1
= StoreArgument
->Common
.Value
.Arg
;
689 Target
= Argument1
->Common
.Next
;
691 if (!AcpiDmIsValidTarget (Target
))
693 StoreOp
->Common
.DisasmFlags
|= ACPI_PARSEOP_LEGACY_ASL_ONLY
;
706 /*******************************************************************************
708 * FUNCTION: AcpiDmCloseOperator
710 * PARAMETERS: Op - Current parse object
714 * DESCRIPTION: Closes an operator by adding a closing parentheses if and
715 * when necessary. Called during ascending phase of the
718 ******************************************************************************/
721 AcpiDmCloseOperator (
722 ACPI_PARSE_OBJECT
*Op
)
725 /* Always emit paren if ASL+ disassembly disabled */
727 if (!AcpiGbl_CstyleDisassembly
)
730 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_END_NODE
, NULL
, 0);
734 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_LEGACY_ASL_ONLY
)
737 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_END_NODE
, NULL
, 0);
741 /* Check if we need to add an additional closing paren */
743 switch (Op
->Common
.AmlOpcode
)
746 case AML_SUBTRACT_OP
:
747 case AML_MULTIPLY_OP
:
750 case AML_SHIFT_LEFT_OP
:
751 case AML_SHIFT_RIGHT_OP
:
755 case AML_LOGICAL_AND_OP
:
756 case AML_LOGICAL_EQUAL_OP
:
757 case AML_LOGICAL_GREATER_OP
:
758 case AML_LOGICAL_LESS_OP
:
759 case AML_LOGICAL_OR_OP
:
761 /* Emit paren only if this is not a compound assignment */
763 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_COMPOUND_ASSIGNMENT
)
765 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_END_NODE
, NULL
, 0);
769 /* Emit extra close paren for assignment within an expression */
771 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_ASSIGNMENT
)
779 /* This is case for unsupported Index() source constants */
781 if (Op
->Common
.DisasmFlags
& ACPI_PARSEOP_CLOSING_PAREN
)
785 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_END_NODE
, NULL
, 0);
788 /* No need for parens for these */
790 case AML_DECREMENT_OP
:
791 case AML_INCREMENT_OP
:
792 case AML_LOGICAL_NOT_OP
:
795 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_END_NODE
, NULL
, 0);
800 /* Always emit paren for non-ASL+ operators */
805 ASL_CV_PRINT_ONE_COMMENT (Op
, AML_COMMENT_END_NODE
, NULL
, 0);
811 /*******************************************************************************
813 * FUNCTION: AcpiDmGetCompoundSymbol
815 * PARAMETERS: AslOpcode
817 * RETURN: String containing the compound assignment symbol
819 * DESCRIPTION: Detect opcodes that can be converted to compound assignment,
820 * return the appropriate operator string.
822 ******************************************************************************/
825 AcpiDmGetCompoundSymbol (
837 case AML_SUBTRACT_OP
:
841 case AML_MULTIPLY_OP
:
853 case AML_SHIFT_LEFT_OP
:
857 case AML_SHIFT_RIGHT_OP
:
875 /* No operator string for all other opcodes */
884 /*******************************************************************************
886 * FUNCTION: AcpiDmPromoteTarget
888 * PARAMETERS: Op - Operator parse object
889 * Target - Target associate with the Op
893 * DESCRIPTION: Transform the parse tree by moving the target up to the first
896 ******************************************************************************/
899 AcpiDmPromoteTarget (
900 ACPI_PARSE_OBJECT
*Op
,
901 ACPI_PARSE_OBJECT
*Target
)
903 ACPI_PARSE_OBJECT
*Child
;
906 /* Link target directly to the Op as first child */
908 Child
= Op
->Common
.Value
.Arg
;
909 Op
->Common
.Value
.Arg
= Target
;
910 Target
->Common
.Next
= Child
;
912 /* Find the last peer, it is linked to the target. Unlink it. */
914 while (Child
->Common
.Next
!= Target
)
916 Child
= Child
->Common
.Next
;
919 Child
->Common
.Next
= NULL
;
923 /*******************************************************************************
925 * FUNCTION: AcpiDmIsValidTarget
927 * PARAMETERS: Target - Target Op from the parse tree
929 * RETURN: TRUE if the Target is real. FALSE if it is just a placeholder
930 * Op that was inserted by the parser.
932 * DESCRIPTION: Determine if a Target Op is a placeholder Op or a real Target.
933 * In other words, determine if the optional target is used or
934 * not. Note: If Target is NULL, something is seriously wrong,
935 * probably with the parse tree.
937 ******************************************************************************/
940 AcpiDmIsValidTarget (
941 ACPI_PARSE_OBJECT
*Target
)
949 if ((Target
->Common
.AmlOpcode
== AML_INT_NAMEPATH_OP
) &&
950 (Target
->Common
.Value
.Arg
== NULL
))
959 /*******************************************************************************
961 * FUNCTION: AcpiDmIsTargetAnOperand
963 * PARAMETERS: Target - Target associated with the expression
964 * Operand - An operand associated with expression
966 * RETURN: TRUE if expression can be converted to a compound assignment.
969 * DESCRIPTION: Determine if the Target duplicates the operand, in order to
970 * detect if the expression can be converted to a compound
971 * assigment. (+=, *=, etc.)
973 ******************************************************************************/
976 AcpiDmIsTargetAnOperand (
977 ACPI_PARSE_OBJECT
*Target
,
978 ACPI_PARSE_OBJECT
*Operand
,
981 const ACPI_OPCODE_INFO
*OpInfo
;
986 * Opcodes must match. Note: ignoring the difference between nameseg
987 * and namepath for now. May be needed later.
989 if (Target
->Common
.AmlOpcode
!= Operand
->Common
.AmlOpcode
)
994 /* Nodes should match, even if they are NULL */
996 if (Target
->Common
.Node
!= Operand
->Common
.Node
)
1001 /* Determine if a child exists */
1003 OpInfo
= AcpiPsGetOpcodeInfo (Operand
->Common
.AmlOpcode
);
1004 if (OpInfo
->Flags
& AML_HAS_ARGS
)
1006 Same
= AcpiDmIsTargetAnOperand (Target
->Common
.Value
.Arg
,
1007 Operand
->Common
.Value
.Arg
, FALSE
);
1014 /* Check the next peer, as long as we are not at the top level */
1017 Target
->Common
.Next
)
1019 Same
= AcpiDmIsTargetAnOperand (Target
->Common
.Next
,
1020 Operand
->Common
.Next
, FALSE
);
1027 /* Supress the duplicate operand at the top-level */
1031 Operand
->Common
.DisasmFlags
|= ACPI_PARSEOP_IGNORE
;