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