aslparseop.c revision 1.1 1 /******************************************************************************
2 *
3 * Module Name: aslparseop - Parse op create/allocate/cache interfaces
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2017, 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 "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #include "acapps.h"
47 #include "acconvert.h"
48
49 #define _COMPONENT ACPI_COMPILER
50 ACPI_MODULE_NAME ("aslparseop")
51
52
53 /* Local prototypes */
54
55 static ACPI_PARSE_OBJECT *
56 TrGetOpFromCache (
57 void);
58
59
60 /*******************************************************************************
61 *
62 * FUNCTION: TrCreateOp
63 *
64 * PARAMETERS: ParseOpcode - Opcode to be assigned to the op
65 * NumChildren - Number of children to follow
66 * ... - A list of child ops to link to the new
67 * op. NumChildren long.
68 *
69 * RETURN: Pointer to the new op. Aborts on allocation failure
70 *
71 * DESCRIPTION: Create a new parse op and link together a list of child
72 * ops underneath the new op.
73 *
74 ******************************************************************************/
75
76 ACPI_PARSE_OBJECT *
77 TrCreateOp (
78 UINT32 ParseOpcode,
79 UINT32 NumChildren,
80 ...)
81 {
82 ACPI_PARSE_OBJECT *Op;
83 ACPI_PARSE_OBJECT *Child;
84 ACPI_PARSE_OBJECT *PrevChild;
85 va_list ap;
86 UINT32 i;
87 BOOLEAN FirstChild;
88
89
90 va_start (ap, NumChildren);
91
92 /* Allocate one new op */
93
94 Op = TrAllocateOp (ParseOpcode);
95
96 DbgPrint (ASL_PARSE_OUTPUT,
97 "\nCreateOp Ln/Col %u/%u NewParent %p Child %u Op %s ",
98 Op->Asl.LineNumber, Op->Asl.Column, Op,
99 NumChildren, UtGetOpName(ParseOpcode));
100
101 /* Some extra debug output based on the parse opcode */
102
103 switch (ParseOpcode)
104 {
105 case PARSEOP_ASL_CODE:
106
107 Gbl_ParseTreeRoot = Op;
108 Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
109 DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->");
110 break;
111
112 case PARSEOP_DEFINITION_BLOCK:
113
114 DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
115 break;
116
117 case PARSEOP_OPERATIONREGION:
118
119 DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
120 break;
121
122 case PARSEOP_OR:
123
124 DbgPrint (ASL_PARSE_OUTPUT, "OR->");
125 break;
126
127 default:
128
129 /* Nothing to do for other opcodes */
130
131 break;
132 }
133
134 /* Link the new op to its children */
135
136 PrevChild = NULL;
137 FirstChild = TRUE;
138 for (i = 0; i < NumChildren; i++)
139 {
140 /* Get the next child */
141
142 Child = va_arg (ap, ACPI_PARSE_OBJECT *);
143 DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
144
145 /*
146 * If child is NULL, this means that an optional argument
147 * was omitted. We must create a placeholder with a special
148 * opcode (DEFAULT_ARG) so that the code generator will know
149 * that it must emit the correct default for this argument
150 */
151 if (!Child)
152 {
153 Child = TrAllocateOp (PARSEOP_DEFAULT_ARG);
154 }
155
156 /* Link first child to parent */
157
158 if (FirstChild)
159 {
160 FirstChild = FALSE;
161 Op->Asl.Child = Child;
162
163 /*
164 * For the ASL-/ASL+ converter: if the ParseOp is a Connection,
165 * External, Offset or AccessAs, it means that the comments in the
166 * FirstChild belongs to their parent due to the parsing order in
167 * the .y files. To correct this, take the comments in the
168 * FirstChild place it in the parent. This also means that
169 * legitimate comments for the child gets put to the parent.
170 */
171 if (Gbl_CaptureComments &&
172 ((ParseOpcode == PARSEOP_CONNECTION) ||
173 (ParseOpcode == PARSEOP_EXTERNAL) ||
174 (ParseOpcode == PARSEOP_OFFSET) ||
175 (ParseOpcode == PARSEOP_ACCESSAS)))
176 {
177 Op->Asl.CommentList = Child->Asl.CommentList;
178 Op->Asl.EndBlkComment = Child->Asl.EndBlkComment;
179 Op->Asl.InlineComment = Child->Asl.InlineComment;
180 Op->Asl.FileChanged = Child->Asl.FileChanged;
181
182 Child->Asl.CommentList = NULL;
183 Child->Asl.EndBlkComment = NULL;
184 Child->Asl.InlineComment = NULL;
185 Child->Asl.FileChanged = FALSE;
186
187 /*
188 * These do not need to be "passed off". They can be copied
189 * because the code for these opcodes should be printed in the
190 * same file.
191 */
192 Op->Asl.Filename = Child->Asl.Filename;
193 Op->Asl.ParentFilename = Child->Asl.ParentFilename;
194 }
195 }
196
197 /* Point all children to parent */
198
199 Child->Asl.Parent = Op;
200
201 /* Link children in a peer list */
202
203 if (PrevChild)
204 {
205 PrevChild->Asl.Next = Child;
206 };
207
208 /* Get the comment from last child in the resource template call */
209
210 if (Gbl_CaptureComments &&
211 (Op->Asl.ParseOpcode == PARSEOP_RESOURCETEMPLATE))
212 {
213 CvDbgPrint ("Transferred current comment list to this op.\n");
214 Op->Asl.CommentList = Child->Asl.CommentList;
215 Child->Asl.CommentList = NULL;
216
217 Op->Asl.InlineComment = Child->Asl.InlineComment;
218 Child->Asl.InlineComment = NULL;
219 }
220
221 /*
222 * This child might be a list, point all ops in the list
223 * to the same parent
224 */
225 while (Child->Asl.Next)
226 {
227 Child = Child->Asl.Next;
228 Child->Asl.Parent = Op;
229 }
230
231 PrevChild = Child;
232 }
233
234 va_end(ap);
235 DbgPrint (ASL_PARSE_OUTPUT, "\n");
236 return (Op);
237 }
238
239
240 /*******************************************************************************
241 *
242 * FUNCTION: TrCreateLeafOp
243 *
244 * PARAMETERS: ParseOpcode - New opcode to be assigned to the op
245 *
246 * RETURN: Pointer to the new op. Aborts on allocation failure
247 *
248 * DESCRIPTION: Create a simple leaf op (no children or peers, and no value
249 * assigned to the op)
250 *
251 ******************************************************************************/
252
253 ACPI_PARSE_OBJECT *
254 TrCreateLeafOp (
255 UINT32 ParseOpcode)
256 {
257 ACPI_PARSE_OBJECT *Op;
258
259
260 Op = TrAllocateOp (ParseOpcode);
261
262 DbgPrint (ASL_PARSE_OUTPUT,
263 "\nCreateLeafOp Ln/Col %u/%u NewOp %p Op %s\n\n",
264 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode));
265
266 return (Op);
267 }
268
269
270 /*******************************************************************************
271 *
272 * FUNCTION: TrCreateValuedLeafOp
273 *
274 * PARAMETERS: ParseOpcode - New opcode to be assigned to the op
275 * Value - Value to be assigned to the op
276 *
277 * RETURN: Pointer to the new op. Aborts on allocation failure
278 *
279 * DESCRIPTION: Create a leaf op (no children or peers) with a value
280 * assigned to it
281 *
282 ******************************************************************************/
283
284 ACPI_PARSE_OBJECT *
285 TrCreateValuedLeafOp (
286 UINT32 ParseOpcode,
287 UINT64 Value)
288 {
289 ACPI_PARSE_OBJECT *Op;
290
291
292 Op = TrAllocateOp (ParseOpcode);
293 Op->Asl.Value.Integer = Value;
294
295 DbgPrint (ASL_PARSE_OUTPUT,
296 "\nCreateValuedLeafOp Ln/Col %u/%u NewOp %p "
297 "Op %s Value %8.8X%8.8X ",
298 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
299 ACPI_FORMAT_UINT64 (Value));
300
301 switch (ParseOpcode)
302 {
303 case PARSEOP_STRING_LITERAL:
304
305 DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value);
306 break;
307
308 case PARSEOP_NAMESEG:
309
310 DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value);
311 break;
312
313 case PARSEOP_NAMESTRING:
314
315 DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value);
316 break;
317
318 case PARSEOP_EISAID:
319
320 DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value);
321 break;
322
323 case PARSEOP_METHOD:
324
325 DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
326 break;
327
328 case PARSEOP_INTEGER:
329
330 DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X",
331 ACPI_FORMAT_UINT64 (Value));
332 break;
333
334 default:
335 break;
336 }
337
338 DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
339 return (Op);
340 }
341
342
343 /*******************************************************************************
344 *
345 * FUNCTION: TrCreateTargetOp
346 *
347 * PARAMETERS: OriginalOp - Op to be copied
348 *
349 * RETURN: Pointer to the new op. Aborts on allocation failure
350 *
351 * DESCRIPTION: Copy an existing op (and subtree). Used in ASL+ (C-style)
352 * expressions where the target is the same as one of the
353 * operands. A new op and subtree must be created from the
354 * original so that the parse tree can be linked properly.
355 *
356 * NOTE: This code is specific to target operands that are the last
357 * operand in an ASL/AML operator. Meaning that the top-level
358 * parse Op in a possible subtree has a NULL Next pointer.
359 * This simplifies the recursion.
360 *
361 * Subtree example:
362 * DeRefOf (Local1) += 32
363 *
364 * This gets converted to:
365 * Add (DeRefOf (Local1), 32, DeRefOf (Local1))
366 *
367 * Each DeRefOf has a single child, Local1. Even more complex
368 * subtrees can be created via the Index and DeRefOf operators.
369 *
370 ******************************************************************************/
371
372 ACPI_PARSE_OBJECT *
373 TrCreateTargetOp (
374 ACPI_PARSE_OBJECT *OriginalOp,
375 ACPI_PARSE_OBJECT *ParentOp)
376 {
377 ACPI_PARSE_OBJECT *Op;
378
379
380 if (!OriginalOp)
381 {
382 return (NULL);
383 }
384
385 Op = TrGetOpFromCache ();
386
387 /* Copy the pertinent values (omit link pointer fields) */
388
389 Op->Asl.Value = OriginalOp->Asl.Value;
390 Op->Asl.Filename = OriginalOp->Asl.Filename;
391 Op->Asl.LineNumber = OriginalOp->Asl.LineNumber;
392 Op->Asl.LogicalLineNumber = OriginalOp->Asl.LogicalLineNumber;
393 Op->Asl.LogicalByteOffset = OriginalOp->Asl.LogicalByteOffset;
394 Op->Asl.Column = OriginalOp->Asl.Column;
395 Op->Asl.Flags = OriginalOp->Asl.Flags;
396 Op->Asl.CompileFlags = OriginalOp->Asl.CompileFlags;
397 Op->Asl.AmlOpcode = OriginalOp->Asl.AmlOpcode;
398 Op->Asl.ParseOpcode = OriginalOp->Asl.ParseOpcode;
399 Op->Asl.Parent = ParentOp;
400
401 UtSetParseOpName (Op);
402
403 /* Copy a possible subtree below this op */
404
405 if (OriginalOp->Asl.Child)
406 {
407 Op->Asl.Child = TrCreateTargetOp (OriginalOp->Asl.Child, Op);
408 }
409
410 if (OriginalOp->Asl.Next) /* Null for top-level op */
411 {
412 Op->Asl.Next = TrCreateTargetOp (OriginalOp->Asl.Next, ParentOp);
413 }
414
415 return (Op);
416 }
417
418
419 /*******************************************************************************
420 *
421 * FUNCTION: TrCreateAssignmentOp
422 *
423 * PARAMETERS: Target - Assignment target
424 * Source - Assignment source
425 *
426 * RETURN: Pointer to the new op. Aborts on allocation failure
427 *
428 * DESCRIPTION: Implements the C-style '=' operator. It changes the parse
429 * tree if possible to utilize the last argument of the math
430 * operators which is a target operand -- thus saving invocation
431 * of and additional Store() operator. An optimization.
432 *
433 ******************************************************************************/
434
435 ACPI_PARSE_OBJECT *
436 TrCreateAssignmentOp (
437 ACPI_PARSE_OBJECT *Target,
438 ACPI_PARSE_OBJECT *Source)
439 {
440 ACPI_PARSE_OBJECT *TargetOp;
441 ACPI_PARSE_OBJECT *SourceOp1;
442 ACPI_PARSE_OBJECT *SourceOp2;
443 ACPI_PARSE_OBJECT *Operator;
444
445
446 DbgPrint (ASL_PARSE_OUTPUT,
447 "\nTrCreateAssignmentOp Line [%u to %u] Source %s Target %s\n",
448 Source->Asl.LineNumber, Source->Asl.EndLine,
449 UtGetOpName (Source->Asl.ParseOpcode),
450 UtGetOpName (Target->Asl.ParseOpcode));
451
452 TrSetOpFlags (Target, OP_IS_TARGET);
453
454 switch (Source->Asl.ParseOpcode)
455 {
456 /*
457 * Only these operators can be optimized because they have
458 * a target operand
459 */
460 case PARSEOP_ADD:
461 case PARSEOP_AND:
462 case PARSEOP_DIVIDE:
463 case PARSEOP_INDEX:
464 case PARSEOP_MOD:
465 case PARSEOP_MULTIPLY:
466 case PARSEOP_NOT:
467 case PARSEOP_OR:
468 case PARSEOP_SHIFTLEFT:
469 case PARSEOP_SHIFTRIGHT:
470 case PARSEOP_SUBTRACT:
471 case PARSEOP_XOR:
472
473 break;
474
475 /* Otherwise, just create a normal Store operator */
476
477 default:
478 goto CannotOptimize;
479 }
480
481 /*
482 * Transform the parse tree such that the target is moved to the
483 * last operand of the operator
484 */
485 SourceOp1 = Source->Asl.Child;
486 SourceOp2 = SourceOp1->Asl.Next;
487
488 /* NOT only has one operand, but has a target */
489
490 if (Source->Asl.ParseOpcode == PARSEOP_NOT)
491 {
492 SourceOp2 = SourceOp1;
493 }
494
495 /* DIVIDE has an extra target operand (remainder) */
496
497 if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE)
498 {
499 SourceOp2 = SourceOp2->Asl.Next;
500 }
501
502 TargetOp = SourceOp2->Asl.Next;
503
504 /*
505 * Can't perform this optimization if there already is a target
506 * for the operator (ZERO is a "no target" placeholder).
507 */
508 if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO)
509 {
510 goto CannotOptimize;
511 }
512
513 /* Link in the target as the final operand */
514
515 SourceOp2->Asl.Next = Target;
516 Target->Asl.Parent = Source;
517 return (Source);
518
519
520 CannotOptimize:
521
522 Operator = TrAllocateOp (PARSEOP_STORE);
523 TrLinkOpChildren (Operator, 2, Source, Target);
524
525 /* Set the appropriate line numbers for the new op */
526
527 Operator->Asl.LineNumber = Target->Asl.LineNumber;
528 Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber;
529 Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset;
530 Operator->Asl.Column = Target->Asl.Column;
531
532 return (Operator);
533 }
534
535
536 /*******************************************************************************
537 *
538 * FUNCTION: TrCreateNullTargetOp
539 *
540 * PARAMETERS: None
541 *
542 * RETURN: Pointer to the new op. Aborts on allocation failure
543 *
544 * DESCRIPTION: Create a "null" target op. This is defined by the ACPI
545 * specification to be a zero AML opcode, and indicates that
546 * no target has been specified for the parent operation
547 *
548 ******************************************************************************/
549
550 ACPI_PARSE_OBJECT *
551 TrCreateNullTargetOp (
552 void)
553 {
554 ACPI_PARSE_OBJECT *Op;
555
556
557 Op = TrAllocateOp (PARSEOP_ZERO);
558 Op->Asl.CompileFlags |= (OP_IS_TARGET | OP_COMPILE_TIME_CONST);
559
560 DbgPrint (ASL_PARSE_OUTPUT,
561 "\nCreateNullTargetOp Ln/Col %u/%u NewOp %p Op %s\n",
562 Op->Asl.LineNumber, Op->Asl.Column, Op,
563 UtGetOpName (Op->Asl.ParseOpcode));
564
565 return (Op);
566 }
567
568
569 /*******************************************************************************
570 *
571 * FUNCTION: TrCreateConstantLeafOp
572 *
573 * PARAMETERS: ParseOpcode - The constant opcode
574 *
575 * RETURN: Pointer to the new op. Aborts on allocation failure
576 *
577 * DESCRIPTION: Create a leaf op (no children or peers) for one of the
578 * special constants - __LINE__, __FILE__, and __DATE__.
579 *
580 * Note: The fullimplemenation of __METHOD__ cannot happen here because we
581 * don't have a full parse tree at this time and cannot find the parent
582 * control method. __METHOD__ must be implemented later, after the parse
583 * tree has been fully constructed.
584 *
585 ******************************************************************************/
586
587 ACPI_PARSE_OBJECT *
588 TrCreateConstantLeafOp (
589 UINT32 ParseOpcode)
590 {
591 ACPI_PARSE_OBJECT *Op = NULL;
592 time_t CurrentTime;
593 char *StaticTimeString;
594 char *TimeString;
595 char *Filename;
596
597
598 switch (ParseOpcode)
599 {
600 case PARSEOP___LINE__:
601
602 Op = TrAllocateOp (PARSEOP_INTEGER);
603 Op->Asl.Value.Integer = Op->Asl.LineNumber;
604 break;
605
606 case PARSEOP___METHOD__:
607
608 /* Will become a string literal later */
609
610 Op = TrAllocateOp (PARSEOP___METHOD__);
611 Op->Asl.Value.String = NULL;
612 break;
613
614 case PARSEOP___PATH__:
615
616 Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
617
618 /* Op.Asl.Filename contains the full pathname to the file */
619
620 Op->Asl.Value.String = Op->Asl.Filename;
621 break;
622
623 case PARSEOP___FILE__:
624
625 Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
626
627 /* Get the simple filename from the full path */
628
629 FlSplitInputPathname (Op->Asl.Filename, NULL, &Filename);
630 Op->Asl.Value.String = Filename;
631 break;
632
633 case PARSEOP___DATE__:
634
635 Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
636
637 /* Get a copy of the current time */
638
639 CurrentTime = time (NULL);
640 StaticTimeString = ctime (&CurrentTime);
641 TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
642 strcpy (TimeString, StaticTimeString);
643
644 TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */
645 Op->Asl.Value.String = TimeString;
646 break;
647
648 default: /* This would be an internal error */
649
650 return (NULL);
651 }
652
653 DbgPrint (ASL_PARSE_OUTPUT,
654 "\nCreateConstantLeafOp Ln/Col %u/%u NewOp %p "
655 "Op %s Value %8.8X%8.8X \n",
656 Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
657 ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
658
659 return (Op);
660 }
661
662
663 /*******************************************************************************
664 *
665 * FUNCTION: TrAllocateOp
666 *
667 * PARAMETERS: ParseOpcode - Opcode to be assigned to the op
668 *
669 * RETURN: New parse op. Aborts on allocation failure
670 *
671 * DESCRIPTION: Allocate and initialize a new parse op for the parse tree
672 *
673 ******************************************************************************/
674
675 ACPI_PARSE_OBJECT *
676 TrAllocateOp (
677 UINT32 ParseOpcode)
678 {
679 ACPI_PARSE_OBJECT *Op;
680 ACPI_PARSE_OBJECT *LatestOp;
681
682
683 Op = TrGetOpFromCache ();
684
685 Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
686 Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename;
687 Op->Asl.LineNumber = Gbl_CurrentLineNumber;
688 Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber;
689 Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset;
690 Op->Asl.Column = Gbl_CurrentColumn;
691
692 UtSetParseOpName (Op);
693
694 /* The following is for capturing comments */
695
696 if(Gbl_CaptureComments)
697 {
698 LatestOp = Gbl_CommentState.LatestParseOp;
699 Op->Asl.InlineComment = NULL;
700 Op->Asl.EndNodeComment = NULL;
701 Op->Asl.CommentList = NULL;
702 Op->Asl.FileChanged = FALSE;
703
704 /*
705 * Check to see if the file name has changed before resetting the
706 * latest parse op.
707 */
708 if (LatestOp &&
709 (ParseOpcode != PARSEOP_INCLUDE) &&
710 (ParseOpcode != PARSEOP_INCLUDE_END) &&
711 strcmp (LatestOp->Asl.Filename, Op->Asl.Filename))
712 {
713 CvDbgPrint ("latest op: %s\n", LatestOp->Asl.ParseOpName);
714 Op->Asl.FileChanged = TRUE;
715 if (Gbl_IncludeFileStack)
716 {
717 Op->Asl.ParentFilename = Gbl_IncludeFileStack->Filename;
718 }
719 else
720 {
721 Op->Asl.ParentFilename = NULL;
722 }
723 }
724
725 Gbl_CommentState.LatestParseOp = Op;
726 CvDbgPrint ("TrAllocateOp=Set latest parse op to this op.\n");
727 CvDbgPrint (" Op->Asl.ParseOpName = %s\n",
728 Gbl_CommentState.LatestParseOp->Asl.ParseOpName);
729 CvDbgPrint (" Op->Asl.ParseOpcode = 0x%x\n", ParseOpcode);
730
731 if (Op->Asl.FileChanged)
732 {
733 CvDbgPrint(" file has been changed!\n");
734 }
735
736 /*
737 * if this parse op's syntax uses () and {} (i.e. Package(1){0x00}) then
738 * set a flag in the comment state. This facilitates paring comments for
739 * these types of opcodes.
740 */
741 if ((CvParseOpBlockType(Op) == (BLOCK_PAREN | BLOCK_BRACE)) &&
742 (ParseOpcode != PARSEOP_DEFINITION_BLOCK))
743 {
744 CvDbgPrint ("Parsing paren/Brace op now!\n");
745 Gbl_CommentState.ParsingParenBraceNode = Op;
746 }
747
748 if (Gbl_CommentListHead)
749 {
750 CvDbgPrint ("Transferring...\n");
751 Op->Asl.CommentList = Gbl_CommentListHead;
752 Gbl_CommentListHead = NULL;
753 Gbl_CommentListTail = NULL;
754 CvDbgPrint (" Transferred current comment list to this op.\n");
755 CvDbgPrint (" %s\n", Op->Asl.CommentList->Comment);
756 }
757
758 if (Gbl_InlineCommentBuffer)
759 {
760 Op->Asl.InlineComment = Gbl_InlineCommentBuffer;
761 Gbl_InlineCommentBuffer = NULL;
762 CvDbgPrint ("Transferred current inline comment list to this op.\n");
763 }
764 }
765
766 return (Op);
767 }
768
769
770 /*******************************************************************************
771 *
772 * FUNCTION: TrGetOpFromCache
773 *
774 * PARAMETERS: None
775 *
776 * RETURN: New parse op. Aborts on allocation failure
777 *
778 * DESCRIPTION: Allocate a new parse op for the parse tree. Bypass the local
779 * dynamic memory manager for performance reasons (This has a
780 * major impact on the speed of the compiler.)
781 *
782 ******************************************************************************/
783
784 static ACPI_PARSE_OBJECT *
785 TrGetOpFromCache (
786 void)
787 {
788 ASL_CACHE_INFO *Cache;
789
790
791 if (Gbl_ParseOpCacheNext >= Gbl_ParseOpCacheLast)
792 {
793 /* Allocate a new buffer */
794
795 Cache = UtLocalCalloc (sizeof (Cache->Next) +
796 (sizeof (ACPI_PARSE_OBJECT) * ASL_PARSEOP_CACHE_SIZE));
797
798 /* Link new cache buffer to head of list */
799
800 Cache->Next = Gbl_ParseOpCacheList;
801 Gbl_ParseOpCacheList = Cache;
802
803 /* Setup cache management pointers */
804
805 Gbl_ParseOpCacheNext = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Cache->Buffer);
806 Gbl_ParseOpCacheLast = Gbl_ParseOpCacheNext + ASL_PARSEOP_CACHE_SIZE;
807 }
808
809 Gbl_ParseOpCount++;
810 return (Gbl_ParseOpCacheNext++);
811 }
812
813
814 /*******************************************************************************
815 *
816 * FUNCTION: TrPrintOpFlags
817 *
818 * PARAMETERS: Flags - Flags word to be decoded
819 * OutputLevel - Debug output level: ASL_TREE_OUTPUT etc.
820 *
821 * RETURN: None
822 *
823 * DESCRIPTION: Decode a flags word to text. Displays all flags that are set.
824 *
825 ******************************************************************************/
826
827 void
828 TrPrintOpFlags (
829 UINT32 Flags,
830 UINT32 OutputLevel)
831 {
832 UINT32 FlagBit = 1;
833 UINT32 i;
834
835
836 for (i = 0; i < ACPI_NUM_OP_FLAGS; i++)
837 {
838 if (Flags & FlagBit)
839 {
840 DbgPrint (OutputLevel, " %s", Gbl_OpFlagNames[i]);
841 }
842
843 FlagBit <<= 1;
844 }
845 }
846