asltransform.c revision 1.1.1.2.8.2 1
2 /******************************************************************************
3 *
4 * Module Name: asltransform - Parse tree transforms
5 *
6 *****************************************************************************/
7
8 /*
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
30 *
31 * NO WARRANTY
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
43 */
44
45
46 #include "aslcompiler.h"
47 #include "aslcompiler.y.h"
48
49 #define _COMPONENT ACPI_COMPILER
50 ACPI_MODULE_NAME ("asltransform")
51
52 /* Local prototypes */
53
54 static void
55 TrTransformSubtree (
56 ACPI_PARSE_OBJECT *Op);
57
58 static char *
59 TrAmlGetNextTempName (
60 ACPI_PARSE_OBJECT *Op,
61 UINT8 *TempCount);
62
63 static void
64 TrAmlInitLineNumbers (
65 ACPI_PARSE_OBJECT *Op,
66 ACPI_PARSE_OBJECT *Neighbor);
67
68 static void
69 TrAmlInitNode (
70 ACPI_PARSE_OBJECT *Op,
71 UINT16 ParseOpcode);
72
73 static void
74 TrAmlSetSubtreeParent (
75 ACPI_PARSE_OBJECT *Op,
76 ACPI_PARSE_OBJECT *Parent);
77
78 static void
79 TrAmlInsertPeer (
80 ACPI_PARSE_OBJECT *Op,
81 ACPI_PARSE_OBJECT *NewPeer);
82
83 static void
84 TrDoDefinitionBlock (
85 ACPI_PARSE_OBJECT *Op);
86
87 static void
88 TrDoSwitch (
89 ACPI_PARSE_OBJECT *StartNode);
90
91
92 /*******************************************************************************
93 *
94 * FUNCTION: TrAmlGetNextTempName
95 *
96 * PARAMETERS: Op - Current parse op
97 * TempCount - Current temporary counter. Was originally
98 * per-module; Currently per method, could be
99 * expanded to per-scope.
100 *
101 * RETURN: A pointer to name (allocated here).
102 *
103 * DESCRIPTION: Generate an ACPI name of the form _T_x. These names are
104 * reserved for use by the ASL compiler. (_T_0 through _T_Z)
105 *
106 ******************************************************************************/
107
108 static char *
109 TrAmlGetNextTempName (
110 ACPI_PARSE_OBJECT *Op,
111 UINT8 *TempCount)
112 {
113 char *TempName;
114
115
116 if (*TempCount >= (10+26)) /* 0-35 valid: 0-9 and A-Z for TempName[3] */
117 {
118 /* Too many temps */
119
120 AslError (ASL_ERROR, ASL_MSG_TOO_MANY_TEMPS, Op, NULL);
121 return (NULL);
122 }
123
124 TempName = UtLocalCalloc (5);
125
126 if (*TempCount < 10) /* 0-9 */
127 {
128 TempName[3] = (char) (*TempCount + '0');
129 }
130 else /* 10-35: A-Z */
131 {
132 TempName[3] = (char) (*TempCount + ('A' - 10));
133 }
134 (*TempCount)++;
135
136 /* First three characters are always "_T_" */
137
138 TempName[0] = '_';
139 TempName[1] = 'T';
140 TempName[2] = '_';
141
142 return (TempName);
143 }
144
145
146 /*******************************************************************************
147 *
148 * FUNCTION: TrAmlInitLineNumbers
149 *
150 * PARAMETERS: Op - Op to be initialized
151 * Neighbor - Op used for initialization values
152 *
153 * RETURN: None
154 *
155 * DESCRIPTION: Initialized the various line numbers for a parse node.
156 *
157 ******************************************************************************/
158
159 static void
160 TrAmlInitLineNumbers (
161 ACPI_PARSE_OBJECT *Op,
162 ACPI_PARSE_OBJECT *Neighbor)
163 {
164
165 Op->Asl.EndLine = Neighbor->Asl.EndLine;
166 Op->Asl.EndLogicalLine = Neighbor->Asl.EndLogicalLine;
167 Op->Asl.LineNumber = Neighbor->Asl.LineNumber;
168 Op->Asl.LogicalByteOffset = Neighbor->Asl.LogicalByteOffset;
169 Op->Asl.LogicalLineNumber = Neighbor->Asl.LogicalLineNumber;
170 }
171
172
173 /*******************************************************************************
174 *
175 * FUNCTION: TrAmlInitNode
176 *
177 * PARAMETERS: Op - Op to be initialized
178 * ParseOpcode - Opcode for this node
179 *
180 * RETURN: None
181 *
182 * DESCRIPTION: Initialize a node with the parse opcode and opcode name.
183 *
184 ******************************************************************************/
185
186 static void
187 TrAmlInitNode (
188 ACPI_PARSE_OBJECT *Op,
189 UINT16 ParseOpcode)
190 {
191
192 Op->Asl.ParseOpcode = ParseOpcode;
193 UtSetParseOpName (Op);
194 }
195
196
197 /*******************************************************************************
198 *
199 * FUNCTION: TrAmlSetSubtreeParent
200 *
201 * PARAMETERS: Op - First node in a list of peer nodes
202 * Parent - Parent of the subtree
203 *
204 * RETURN: None
205 *
206 * DESCRIPTION: Set the parent for all peer nodes in a subtree
207 *
208 ******************************************************************************/
209
210 static void
211 TrAmlSetSubtreeParent (
212 ACPI_PARSE_OBJECT *Op,
213 ACPI_PARSE_OBJECT *Parent)
214 {
215 ACPI_PARSE_OBJECT *Next;
216
217
218 Next = Op;
219 while (Next)
220 {
221 Next->Asl.Parent = Parent;
222 Next = Next->Asl.Next;
223 }
224 }
225
226
227 /*******************************************************************************
228 *
229 * FUNCTION: TrAmlInsertPeer
230 *
231 * PARAMETERS: Op - First node in a list of peer nodes
232 * NewPeer - Peer node to insert
233 *
234 * RETURN: None
235 *
236 * DESCRIPTION: Insert a new peer node into a list of peers.
237 *
238 ******************************************************************************/
239
240 static void
241 TrAmlInsertPeer (
242 ACPI_PARSE_OBJECT *Op,
243 ACPI_PARSE_OBJECT *NewPeer)
244 {
245
246 NewPeer->Asl.Next = Op->Asl.Next;
247 Op->Asl.Next = NewPeer;
248 }
249
250
251 /*******************************************************************************
252 *
253 * FUNCTION: TrAmlTransformWalk
254 *
255 * PARAMETERS: ASL_WALK_CALLBACK
256 *
257 * RETURN: None
258 *
259 * DESCRIPTION: Parse tree walk to generate both the AML opcodes and the AML
260 * operands.
261 *
262 ******************************************************************************/
263
264 ACPI_STATUS
265 TrAmlTransformWalk (
266 ACPI_PARSE_OBJECT *Op,
267 UINT32 Level,
268 void *Context)
269 {
270
271 TrTransformSubtree (Op);
272 return (AE_OK);
273 }
274
275
276 /*******************************************************************************
277 *
278 * FUNCTION: TrTransformSubtree
279 *
280 * PARAMETERS: Op - The parent parse node
281 *
282 * RETURN: None
283 *
284 * DESCRIPTION: Prepare nodes to be output as AML data and operands. The more
285 * complex AML opcodes require processing of the child nodes
286 * (arguments/operands).
287 *
288 ******************************************************************************/
289
290 static void
291 TrTransformSubtree (
292 ACPI_PARSE_OBJECT *Op)
293 {
294
295 if (Op->Asl.AmlOpcode == AML_RAW_DATA_BYTE)
296 {
297 return;
298 }
299
300 switch (Op->Asl.ParseOpcode)
301 {
302 case PARSEOP_DEFINITIONBLOCK:
303 TrDoDefinitionBlock (Op);
304 break;
305
306 case PARSEOP_SWITCH:
307 TrDoSwitch (Op);
308 break;
309
310 case PARSEOP_METHOD:
311
312 /*
313 * TBD: Zero the tempname (_T_x) count. Probably shouldn't be a global,
314 * however
315 */
316 Gbl_TempCount = 0;
317 break;
318
319 default:
320 /* Nothing to do here for other opcodes */
321 break;
322 }
323 }
324
325
326 /*******************************************************************************
327 *
328 * FUNCTION: TrDoDefinitionBlock
329 *
330 * PARAMETERS: Op - Parse node
331 *
332 * RETURN: None
333 *
334 * DESCRIPTION: Find the end of the definition block and set a global to this
335 * node. It is used by the compiler to insert compiler-generated
336 * names at the root level of the namespace.
337 *
338 ******************************************************************************/
339
340 static void
341 TrDoDefinitionBlock (
342 ACPI_PARSE_OBJECT *Op)
343 {
344 ACPI_PARSE_OBJECT *Next;
345 UINT32 i;
346
347
348 Next = Op->Asl.Child;
349 for (i = 0; i < 5; i++)
350 {
351 Next = Next->Asl.Next;
352 if (i == 0)
353 {
354 /*
355 * This is the table signature. Only the DSDT can be assumed
356 * to be at the root of the namespace; Therefore, namepath
357 * optimization can only be performed on the DSDT.
358 */
359 if (!ACPI_COMPARE_NAME (Next->Asl.Value.String, ACPI_SIG_DSDT))
360 {
361 Gbl_ReferenceOptimizationFlag = FALSE;
362 }
363 }
364 }
365
366 Gbl_FirstLevelInsertionNode = Next;
367 }
368
369
370 /*******************************************************************************
371 *
372 * FUNCTION: TrDoSwitch
373 *
374 * PARAMETERS: StartNode - Parse node for SWITCH
375 *
376 * RETURN: None
377 *
378 *
379 * DESCRIPTION: Translate ASL SWITCH statement to if/else pairs. There is
380 * no actual AML opcode for SWITCH -- it must be simulated.
381 *
382 ******************************************************************************/
383
384 static void
385 TrDoSwitch (
386 ACPI_PARSE_OBJECT *StartNode)
387 {
388 ACPI_PARSE_OBJECT *Next;
389 ACPI_PARSE_OBJECT *CaseOp = NULL;
390 ACPI_PARSE_OBJECT *CaseBlock = NULL;
391 ACPI_PARSE_OBJECT *DefaultOp = NULL;
392 ACPI_PARSE_OBJECT *CurrentParentNode;
393 ACPI_PARSE_OBJECT *Conditional = NULL;
394 ACPI_PARSE_OBJECT *Predicate;
395 ACPI_PARSE_OBJECT *Peer;
396 ACPI_PARSE_OBJECT *NewOp;
397 ACPI_PARSE_OBJECT *NewOp2;
398 ACPI_PARSE_OBJECT *MethodOp;
399 ACPI_PARSE_OBJECT *StoreOp;
400 ACPI_PARSE_OBJECT *BreakOp;
401 char *PredicateValueName;
402 UINT16 Index;
403 UINT32 Btype;
404
405
406 /* Start node is the Switch() node */
407
408 CurrentParentNode = StartNode;
409
410 /* Create a new temp name of the form _T_x */
411
412 PredicateValueName = TrAmlGetNextTempName (StartNode, &Gbl_TempCount);
413 if (!PredicateValueName)
414 {
415 return;
416 }
417
418 /* First child is the Switch() predicate */
419
420 Next = StartNode->Asl.Child;
421
422 /*
423 * Examine the return type of the Switch Value -
424 * must be Integer/Buffer/String
425 */
426 Index = (UINT16) (Next->Asl.ParseOpcode - ASL_PARSE_OPCODE_BASE);
427 Btype = AslKeywordMapping[Index].AcpiBtype;
428 if ((Btype != ACPI_BTYPE_INTEGER) &&
429 (Btype != ACPI_BTYPE_STRING) &&
430 (Btype != ACPI_BTYPE_BUFFER))
431 {
432 AslError (ASL_WARNING, ASL_MSG_SWITCH_TYPE, Next, NULL);
433 Btype = ACPI_BTYPE_INTEGER;
434 }
435
436 /* CASE statements start at next child */
437
438 Peer = Next->Asl.Next;
439 while (Peer)
440 {
441 Next = Peer;
442 Peer = Next->Asl.Next;
443
444 if (Next->Asl.ParseOpcode == PARSEOP_CASE)
445 {
446 if (CaseOp)
447 {
448 /* Add an ELSE to complete the previous CASE */
449
450 if (!Conditional)
451 {
452 return;
453 }
454 NewOp = TrCreateLeafNode (PARSEOP_ELSE);
455 NewOp->Asl.Parent = Conditional->Asl.Parent;
456 TrAmlInitLineNumbers (NewOp, NewOp->Asl.Parent);
457
458 /* Link ELSE node as a peer to the previous IF */
459
460 TrAmlInsertPeer (Conditional, NewOp);
461 CurrentParentNode = NewOp;
462 }
463
464 CaseOp = Next;
465 Conditional = CaseOp;
466 CaseBlock = CaseOp->Asl.Child->Asl.Next;
467 Conditional->Asl.Child->Asl.Next = NULL;
468 Predicate = CaseOp->Asl.Child;
469
470 if ((Predicate->Asl.ParseOpcode == PARSEOP_PACKAGE) ||
471 (Predicate->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE))
472 {
473 /*
474 * Convert the package declaration to this form:
475 *
476 * If (LNotEqual (Match (Package(<size>){<data>},
477 * MEQ, _T_x, MTR, Zero, Zero), Ones))
478 */
479 NewOp2 = TrCreateLeafNode (PARSEOP_MATCHTYPE_MEQ);
480 Predicate->Asl.Next = NewOp2;
481 TrAmlInitLineNumbers (NewOp2, Conditional);
482
483 NewOp = NewOp2;
484 NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESTRING,
485 (UINT64) ACPI_TO_INTEGER (PredicateValueName));
486 NewOp->Asl.Next = NewOp2;
487 TrAmlInitLineNumbers (NewOp2, Predicate);
488
489 NewOp = NewOp2;
490 NewOp2 = TrCreateLeafNode (PARSEOP_MATCHTYPE_MTR);
491 NewOp->Asl.Next = NewOp2;
492 TrAmlInitLineNumbers (NewOp2, Predicate);
493
494 NewOp = NewOp2;
495 NewOp2 = TrCreateLeafNode (PARSEOP_ZERO);
496 NewOp->Asl.Next = NewOp2;
497 TrAmlInitLineNumbers (NewOp2, Predicate);
498
499 NewOp = NewOp2;
500 NewOp2 = TrCreateLeafNode (PARSEOP_ZERO);
501 NewOp->Asl.Next = NewOp2;
502 TrAmlInitLineNumbers (NewOp2, Predicate);
503
504 NewOp2 = TrCreateLeafNode (PARSEOP_MATCH);
505 NewOp2->Asl.Child = Predicate; /* PARSEOP_PACKAGE */
506 TrAmlInitLineNumbers (NewOp2, Conditional);
507 TrAmlSetSubtreeParent (Predicate, NewOp2);
508
509 NewOp = NewOp2;
510 NewOp2 = TrCreateLeafNode (PARSEOP_ONES);
511 NewOp->Asl.Next = NewOp2;
512 TrAmlInitLineNumbers (NewOp2, Conditional);
513
514 NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL);
515 NewOp2->Asl.Child = NewOp;
516 NewOp->Asl.Parent = NewOp2;
517 TrAmlInitLineNumbers (NewOp2, Conditional);
518 TrAmlSetSubtreeParent (NewOp, NewOp2);
519
520 NewOp = NewOp2;
521 NewOp2 = TrCreateLeafNode (PARSEOP_LNOT);
522 NewOp2->Asl.Child = NewOp;
523 NewOp2->Asl.Parent = Conditional;
524 NewOp->Asl.Parent = NewOp2;
525 TrAmlInitLineNumbers (NewOp2, Conditional);
526
527 Conditional->Asl.Child = NewOp2;
528 NewOp2->Asl.Next = CaseBlock;
529 }
530 else
531 {
532 /*
533 * Integer and Buffer case.
534 *
535 * Change CaseOp() to: If (LEqual (SwitchValue, CaseValue)) {...}
536 * Note: SwitchValue is first to allow the CaseValue to be implicitly
537 * converted to the type of SwitchValue if necessary.
538 *
539 * CaseOp->Child is the case value
540 * CaseOp->Child->Peer is the beginning of the case block
541 */
542 NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESTRING,
543 (UINT64) ACPI_TO_INTEGER (PredicateValueName));
544 NewOp->Asl.Next = Predicate;
545 TrAmlInitLineNumbers (NewOp, Predicate);
546
547 NewOp2 = TrCreateLeafNode (PARSEOP_LEQUAL);
548 NewOp2->Asl.Parent = Conditional;
549 NewOp2->Asl.Child = NewOp;
550 TrAmlInitLineNumbers (NewOp2, Conditional);
551
552 TrAmlSetSubtreeParent (NewOp, NewOp2);
553
554 Predicate = NewOp2;
555 Predicate->Asl.Next = CaseBlock;
556
557 TrAmlSetSubtreeParent (Predicate, Conditional);
558 Conditional->Asl.Child = Predicate;
559 }
560
561 /* Reinitialize the CASE node to an IF node */
562
563 TrAmlInitNode (Conditional, PARSEOP_IF);
564
565 /*
566 * The first CASE(IF) is not nested under an ELSE.
567 * All other CASEs are children of a parent ELSE.
568 */
569 if (CurrentParentNode == StartNode)
570 {
571 Conditional->Asl.Next = NULL;
572 }
573 else
574 {
575 /*
576 * The IF is a child of previous IF/ELSE. It
577 * is therefore without peer.
578 */
579 CurrentParentNode->Asl.Child = Conditional;
580 Conditional->Asl.Parent = CurrentParentNode;
581 Conditional->Asl.Next = NULL;
582 }
583 }
584 else if (Next->Asl.ParseOpcode == PARSEOP_DEFAULT)
585 {
586 if (DefaultOp)
587 {
588 /*
589 * More than one Default
590 * (Parser does not catch this, must check here)
591 */
592 AslError (ASL_ERROR, ASL_MSG_MULTIPLE_DEFAULT, Next, NULL);
593 }
594 else
595 {
596 /* Save the DEFAULT node for later, after CASEs */
597
598 DefaultOp = Next;
599 }
600 }
601 else
602 {
603 /* Unknown peer opcode */
604
605 AcpiOsPrintf ("Unknown parse opcode for switch statement: %s (%u)\n",
606 Next->Asl.ParseOpName, Next->Asl.ParseOpcode);
607 }
608 }
609
610 /* Add the default case at the end of the if/else construct */
611
612 if (DefaultOp)
613 {
614 /* If no CASE statements, this is an error - see below */
615
616 if (CaseOp)
617 {
618 /* Convert the DEFAULT node to an ELSE */
619
620 if (!Conditional)
621 {
622 return;
623 }
624
625 TrAmlInitNode (DefaultOp, PARSEOP_ELSE);
626 DefaultOp->Asl.Parent = Conditional->Asl.Parent;
627
628 /* Link ELSE node as a peer to the previous IF */
629
630 TrAmlInsertPeer (Conditional, DefaultOp);
631 }
632 }
633
634 if (!CaseOp)
635 {
636 AslError (ASL_ERROR, ASL_MSG_NO_CASES, StartNode, NULL);
637 }
638
639
640 /*
641 * Create a Name(_T_x, ...) statement. This statement must appear at the
642 * method level, in case a loop surrounds the switch statement and could
643 * cause the name to be created twice (error).
644 */
645
646 /* Create the Name node */
647
648 Predicate = StartNode->Asl.Child;
649 NewOp = TrCreateLeafNode (PARSEOP_NAME);
650
651 /* Find the parent method */
652
653 Next = StartNode;
654 while ((Next->Asl.ParseOpcode != PARSEOP_METHOD) &&
655 (Next->Asl.ParseOpcode != PARSEOP_DEFINITIONBLOCK))
656 {
657 Next = Next->Asl.Parent;
658 }
659 MethodOp = Next;
660
661 NewOp->Asl.CompileFlags |= NODE_COMPILER_EMITTED;
662 NewOp->Asl.Parent = Next;
663
664 /* Insert name after the method name and arguments */
665
666 Next = Next->Asl.Child; /* Name */
667 Next = Next->Asl.Next; /* NumArgs */
668 Next = Next->Asl.Next; /* SerializeRule */
669
670 /*
671 * If method is not Serialized, we must make is so, because of the way
672 * that Switch() must be implemented -- we cannot allow multiple threads
673 * to execute this method concurrently since we need to create local
674 * temporary name(s).
675 */
676 if (Next->Asl.ParseOpcode != PARSEOP_SERIALIZERULE_SERIAL)
677 {
678 AslError (ASL_REMARK, ASL_MSG_SERIALIZED, MethodOp, "Due to use of Switch operator");
679 Next->Asl.ParseOpcode = PARSEOP_SERIALIZERULE_SERIAL;
680 }
681
682 Next = Next->Asl.Next; /* SyncLevel */
683 Next = Next->Asl.Next; /* ReturnType */
684 Next = Next->Asl.Next; /* ParameterTypes */
685
686 TrAmlInsertPeer (Next, NewOp);
687 TrAmlInitLineNumbers (NewOp, Next);
688
689 /* Create the NameSeg child for the Name node */
690
691 NewOp2 = TrCreateValuedLeafNode (PARSEOP_NAMESEG,
692 (UINT64) ACPI_TO_INTEGER (PredicateValueName));
693 NewOp2->Asl.CompileFlags |= NODE_IS_NAME_DECLARATION;
694 NewOp->Asl.Child = NewOp2;
695
696 /* Create the initial value for the Name. Btype was already validated above */
697
698 switch (Btype)
699 {
700 case ACPI_BTYPE_INTEGER:
701 NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_ZERO,
702 (UINT64) 0);
703 break;
704
705 case ACPI_BTYPE_STRING:
706 NewOp2->Asl.Next = TrCreateValuedLeafNode (PARSEOP_STRING_LITERAL,
707 (UINT64) ACPI_TO_INTEGER (""));
708 break;
709
710 case ACPI_BTYPE_BUFFER:
711 (void) TrLinkPeerNode (NewOp2, TrCreateValuedLeafNode (PARSEOP_BUFFER,
712 (UINT64) 0));
713 Next = NewOp2->Asl.Next;
714 (void) TrLinkChildren (Next, 1, TrCreateValuedLeafNode (PARSEOP_ZERO,
715 (UINT64) 1));
716 (void) TrLinkPeerNode (Next->Asl.Child,
717 TrCreateValuedLeafNode (PARSEOP_DEFAULT_ARG, (UINT64) 0));
718
719 TrAmlSetSubtreeParent (Next->Asl.Child, Next);
720 break;
721
722 default:
723 break;
724 }
725
726 TrAmlSetSubtreeParent (NewOp2, NewOp);
727
728 /*
729 * Transform the Switch() into a While(One)-Break node.
730 * And create a Store() node which will be used to save the
731 * Switch() value. The store is of the form: Store (Value, _T_x)
732 * where _T_x is the temp variable.
733 */
734 TrAmlInitNode (StartNode, PARSEOP_WHILE);
735 NewOp = TrCreateLeafNode (PARSEOP_ONE);
736 NewOp->Asl.Next = Predicate->Asl.Next;
737 NewOp->Asl.Parent = StartNode;
738 StartNode->Asl.Child = NewOp;
739
740 /* Create a Store() node */
741
742 StoreOp = TrCreateLeafNode (PARSEOP_STORE);
743 StoreOp->Asl.Parent = StartNode;
744 TrAmlInsertPeer (NewOp, StoreOp);
745
746 /* Complete the Store subtree */
747
748 StoreOp->Asl.Child = Predicate;
749 Predicate->Asl.Parent = StoreOp;
750
751 NewOp = TrCreateValuedLeafNode (PARSEOP_NAMESEG,
752 (UINT64) ACPI_TO_INTEGER (PredicateValueName));
753 NewOp->Asl.Parent = StoreOp;
754 Predicate->Asl.Next = NewOp;
755
756 /* Create a Break() node and insert it into the end of While() */
757
758 Conditional = StartNode->Asl.Child;
759 while (Conditional->Asl.Next)
760 {
761 Conditional = Conditional->Asl.Next;
762 }
763
764 BreakOp = TrCreateLeafNode (PARSEOP_BREAK);
765 BreakOp->Asl.Parent = StartNode;
766 TrAmlInsertPeer (Conditional, BreakOp);
767 }
768
769
770