Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/acpica/compiler/aslparseop.c
48373 views
1
/******************************************************************************
2
*
3
* Module Name: aslparseop - Parse op create/allocate/cache interfaces
4
*
5
*****************************************************************************/
6
7
/******************************************************************************
8
*
9
* 1. Copyright Notice
10
*
11
* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12
* All rights reserved.
13
*
14
* 2. License
15
*
16
* 2.1. This is your license from Intel Corp. under its intellectual property
17
* rights. You may have additional license terms from the party that provided
18
* you this software, covering your right to use that party's intellectual
19
* property rights.
20
*
21
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22
* copy of the source code appearing in this file ("Covered Code") an
23
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
24
* base code distributed originally by Intel ("Original Intel Code") to copy,
25
* make derivatives, distribute, use and display any portion of the Covered
26
* Code in any form, with the right to sublicense such rights; and
27
*
28
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29
* license (with the right to sublicense), under only those claims of Intel
30
* patents that are infringed by the Original Intel Code, to make, use, sell,
31
* offer to sell, and import the Covered Code and derivative works thereof
32
* solely to the minimum extent necessary to exercise the above copyright
33
* license, and in no event shall the patent license extend to any additions
34
* to or modifications of the Original Intel Code. No other license or right
35
* is granted directly or by implication, estoppel or otherwise;
36
*
37
* The above copyright and patent license is granted only if the following
38
* conditions are met:
39
*
40
* 3. Conditions
41
*
42
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
43
* Redistribution of source code of any substantial portion of the Covered
44
* Code or modification with rights to further distribute source must include
45
* the above Copyright Notice, the above License, this list of Conditions,
46
* and the following Disclaimer and Export Compliance provision. In addition,
47
* Licensee must cause all Covered Code to which Licensee contributes to
48
* contain a file documenting the changes Licensee made to create that Covered
49
* Code and the date of any change. Licensee must include in that file the
50
* documentation of any changes made by any predecessor Licensee. Licensee
51
* must include a prominent statement that the modification is derived,
52
* directly or indirectly, from Original Intel Code.
53
*
54
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55
* Redistribution of source code of any substantial portion of the Covered
56
* Code or modification without rights to further distribute source must
57
* include the following Disclaimer and Export Compliance provision in the
58
* documentation and/or other materials provided with distribution. In
59
* addition, Licensee may not authorize further sublicense of source of any
60
* portion of the Covered Code, and must include terms to the effect that the
61
* license from Licensee to its licensee is limited to the intellectual
62
* property embodied in the software Licensee provides to its licensee, and
63
* not to intellectual property embodied in modifications its licensee may
64
* make.
65
*
66
* 3.3. Redistribution of Executable. Redistribution in executable form of any
67
* substantial portion of the Covered Code or modification must reproduce the
68
* above Copyright Notice, and the following Disclaimer and Export Compliance
69
* provision in the documentation and/or other materials provided with the
70
* distribution.
71
*
72
* 3.4. Intel retains all right, title, and interest in and to the Original
73
* Intel Code.
74
*
75
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
76
* Intel shall be used in advertising or otherwise to promote the sale, use or
77
* other dealings in products derived from or relating to the Covered Code
78
* without prior written authorization from Intel.
79
*
80
* 4. Disclaimer and Export Compliance
81
*
82
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88
* PARTICULAR PURPOSE.
89
*
90
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97
* LIMITED REMEDY.
98
*
99
* 4.3. Licensee shall not export, either directly or indirectly, any of this
100
* software or system incorporating such software without first obtaining any
101
* required license or other approval from the U. S. Department of Commerce or
102
* any other agency or department of the United States Government. In the
103
* event Licensee exports any such software from the United States or
104
* re-exports any such software from a foreign destination, Licensee shall
105
* ensure that the distribution and export/re-export of the software is in
106
* compliance with all laws, regulations, orders, or other restrictions of the
107
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
108
* any of its subsidiaries will export/re-export any technical data, process,
109
* software, or service, directly or indirectly, to any country for which the
110
* United States government or any agency thereof requires an export license,
111
* other governmental approval, or letter of assurance, without first obtaining
112
* such license, approval or letter.
113
*
114
*****************************************************************************
115
*
116
* Alternatively, you may choose to be licensed under the terms of the
117
* following license:
118
*
119
* Redistribution and use in source and binary forms, with or without
120
* modification, are permitted provided that the following conditions
121
* are met:
122
* 1. Redistributions of source code must retain the above copyright
123
* notice, this list of conditions, and the following disclaimer,
124
* without modification.
125
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
126
* substantially similar to the "NO WARRANTY" disclaimer below
127
* ("Disclaimer") and any redistribution must be conditioned upon
128
* including a substantially similar Disclaimer requirement for further
129
* binary redistribution.
130
* 3. Neither the names of the above-listed copyright holders nor the names
131
* of any contributors may be used to endorse or promote products derived
132
* from this software without specific prior written permission.
133
*
134
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145
*
146
* Alternatively, you may choose to be licensed under the terms of the
147
* GNU General Public License ("GPL") version 2 as published by the Free
148
* Software Foundation.
149
*
150
*****************************************************************************/
151
152
#include <contrib/dev/acpica/compiler/aslcompiler.h>
153
#include "aslcompiler.y.h"
154
#include <contrib/dev/acpica/include/acapps.h>
155
#include <contrib/dev/acpica/include/acconvert.h>
156
157
#define _COMPONENT ACPI_COMPILER
158
ACPI_MODULE_NAME ("aslparseop")
159
160
161
/*******************************************************************************
162
*
163
* FUNCTION: TrCreateOp
164
*
165
* PARAMETERS: ParseOpcode - Opcode to be assigned to the op
166
* NumChildren - Number of children to follow
167
* ... - A list of child ops to link to the new
168
* op. NumChildren long.
169
*
170
* RETURN: Pointer to the new op. Aborts on allocation failure
171
*
172
* DESCRIPTION: Create a new parse op and link together a list of child
173
* ops underneath the new op.
174
*
175
******************************************************************************/
176
177
ACPI_PARSE_OBJECT *
178
TrCreateOp (
179
UINT32 ParseOpcode,
180
UINT32 NumChildren,
181
...)
182
{
183
ACPI_PARSE_OBJECT *Op;
184
ACPI_PARSE_OBJECT *Child;
185
ACPI_PARSE_OBJECT *PrevChild;
186
va_list ap;
187
UINT32 i;
188
BOOLEAN FirstChild;
189
190
191
va_start (ap, NumChildren);
192
193
/* Allocate one new op */
194
195
Op = TrAllocateOp (ParseOpcode);
196
197
DbgPrint (ASL_PARSE_OUTPUT,
198
"\nCreateOp Ln/Col %u/%u NewParent %p Child %u Op %s ",
199
Op->Asl.LineNumber, Op->Asl.Column, Op,
200
NumChildren, UtGetOpName(ParseOpcode));
201
202
/* Some extra debug output based on the parse opcode */
203
204
switch (ParseOpcode)
205
{
206
case PARSEOP_ASL_CODE:
207
208
AslGbl_ParseTreeRoot = Op;
209
Op->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
210
DbgPrint (ASL_PARSE_OUTPUT, "ASLCODE (Tree Completed)->");
211
break;
212
213
case PARSEOP_DEFINITION_BLOCK:
214
215
DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
216
break;
217
218
case PARSEOP_OPERATIONREGION:
219
220
DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
221
break;
222
223
case PARSEOP_OR:
224
225
DbgPrint (ASL_PARSE_OUTPUT, "OR->");
226
break;
227
228
default:
229
230
/* Nothing to do for other opcodes */
231
232
break;
233
}
234
235
/* Link the new op to its children */
236
237
PrevChild = NULL;
238
FirstChild = TRUE;
239
for (i = 0; i < NumChildren; i++)
240
{
241
/* Get the next child */
242
243
Child = va_arg (ap, ACPI_PARSE_OBJECT *);
244
DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
245
246
/*
247
* If child is NULL, this means that an optional argument
248
* was omitted. We must create a placeholder with a special
249
* opcode (DEFAULT_ARG) so that the code generator will know
250
* that it must emit the correct default for this argument
251
*/
252
if (!Child)
253
{
254
Child = TrAllocateOp (PARSEOP_DEFAULT_ARG);
255
}
256
257
/* Link first child to parent */
258
259
if (FirstChild)
260
{
261
FirstChild = FALSE;
262
Op->Asl.Child = Child;
263
264
/*
265
* For the ASL-/ASL+ converter: if the ParseOp is a Connection,
266
* External, Offset or AccessAs, it means that the comments in the
267
* FirstChild belongs to their parent due to the parsing order in
268
* the .y files. To correct this, take the comments in the
269
* FirstChild place it in the parent. This also means that
270
* legitimate comments for the child gets put to the parent.
271
*/
272
if (AcpiGbl_CaptureComments &&
273
((ParseOpcode == PARSEOP_CONNECTION) ||
274
(ParseOpcode == PARSEOP_EXTERNAL) ||
275
(ParseOpcode == PARSEOP_OFFSET) ||
276
(ParseOpcode == PARSEOP_ACCESSAS)))
277
{
278
Op->Asl.CommentList = Child->Asl.CommentList;
279
Op->Asl.EndBlkComment = Child->Asl.EndBlkComment;
280
Op->Asl.InlineComment = Child->Asl.InlineComment;
281
Op->Asl.FileChanged = Child->Asl.FileChanged;
282
283
Child->Asl.CommentList = NULL;
284
Child->Asl.EndBlkComment = NULL;
285
Child->Asl.InlineComment = NULL;
286
Child->Asl.FileChanged = FALSE;
287
288
/*
289
* These do not need to be "passed off". They can be copied
290
* because the code for these opcodes should be printed in the
291
* same file.
292
*/
293
Op->Asl.Filename = Child->Asl.Filename;
294
Op->Asl.ParentFilename = Child->Asl.ParentFilename;
295
}
296
}
297
298
/* Point all children to parent */
299
300
Child->Asl.Parent = Op;
301
302
/* Link children in a peer list */
303
304
if (PrevChild)
305
{
306
PrevChild->Asl.Next = Child;
307
};
308
309
/* Get the comment from last child in the resource template call */
310
311
if (AcpiGbl_CaptureComments &&
312
(Op->Asl.ParseOpcode == PARSEOP_RESOURCETEMPLATE))
313
{
314
CvDbgPrint ("Transferred current comment list to this op.\n");
315
Op->Asl.CommentList = Child->Asl.CommentList;
316
Child->Asl.CommentList = NULL;
317
318
Op->Asl.InlineComment = Child->Asl.InlineComment;
319
Child->Asl.InlineComment = NULL;
320
}
321
322
/*
323
* This child might be a list, point all ops in the list
324
* to the same parent
325
*/
326
while (Child->Asl.Next)
327
{
328
Child = Child->Asl.Next;
329
Child->Asl.Parent = Op;
330
}
331
332
PrevChild = Child;
333
}
334
335
va_end(ap);
336
DbgPrint (ASL_PARSE_OUTPUT, "\n");
337
return (Op);
338
}
339
340
341
/*******************************************************************************
342
*
343
* FUNCTION: TrCreateLeafOp
344
*
345
* PARAMETERS: ParseOpcode - New opcode to be assigned to the op
346
*
347
* RETURN: Pointer to the new op. Aborts on allocation failure
348
*
349
* DESCRIPTION: Create a simple leaf op (no children or peers, and no value
350
* assigned to the op)
351
*
352
******************************************************************************/
353
354
ACPI_PARSE_OBJECT *
355
TrCreateLeafOp (
356
UINT32 ParseOpcode)
357
{
358
ACPI_PARSE_OBJECT *Op;
359
360
361
Op = TrAllocateOp (ParseOpcode);
362
363
DbgPrint (ASL_PARSE_OUTPUT,
364
"\nCreateLeafOp Ln/Col %u/%u NewOp %p Op %s\n\n",
365
Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode));
366
367
return (Op);
368
}
369
370
371
/*******************************************************************************
372
*
373
* FUNCTION: TrCreateValuedLeafOp
374
*
375
* PARAMETERS: ParseOpcode - New opcode to be assigned to the op
376
* Value - Value to be assigned to the op
377
*
378
* RETURN: Pointer to the new op. Aborts on allocation failure
379
*
380
* DESCRIPTION: Create a leaf op (no children or peers) with a value
381
* assigned to it
382
*
383
******************************************************************************/
384
385
ACPI_PARSE_OBJECT *
386
TrCreateValuedLeafOp (
387
UINT32 ParseOpcode,
388
UINT64 Value)
389
{
390
ACPI_PARSE_OBJECT *Op;
391
UINT32 i;
392
char *StringPtr = NULL;
393
394
395
Op = TrAllocateOp (ParseOpcode);
396
Op->Asl.Value.Integer = Value;
397
398
DbgPrint (ASL_PARSE_OUTPUT,
399
"\nCreateValuedLeafOp Ln/Col %u/%u NewOp %p "
400
"Op %s Value %8.8X%8.8X ",
401
Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
402
ACPI_FORMAT_UINT64 (Value));
403
404
switch (ParseOpcode)
405
{
406
case PARSEOP_STRING_LITERAL:
407
408
DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Op->Asl.Value.String);
409
break;
410
411
case PARSEOP_NAMESEG:
412
413
/* Check for mixed case (or all lower case). Issue a remark in this case */
414
415
for (i = 0; i < ACPI_NAMESEG_SIZE; i++)
416
{
417
if (islower ((int) Op->Asl.Value.Name[i]))
418
{
419
AcpiUtStrupr (&Op->Asl.Value.Name[i]);
420
AslError (ASL_REMARK, ASL_MSG_LOWER_CASE_NAMESEG, Op, Op->Asl.Value.Name);
421
break;
422
}
423
}
424
DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Op->Asl.Value.String);
425
break;
426
427
case PARSEOP_NAMESTRING:
428
429
/* Check for mixed case (or all lower case). Issue a remark in this case */
430
431
StringPtr = Op->Asl.Value.Name;
432
for (i = 0; *StringPtr; i++)
433
{
434
if (islower ((int) *StringPtr))
435
{
436
AcpiUtStrupr (&Op->Asl.Value.Name[i]);
437
AslError (ASL_REMARK, ASL_MSG_LOWER_CASE_NAMEPATH, Op, Op->Asl.Value.Name);
438
break;
439
}
440
StringPtr++;
441
}
442
DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Op->Asl.Value.String);
443
break;
444
445
case PARSEOP_EISAID:
446
447
DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Op->Asl.Value.String);
448
break;
449
450
case PARSEOP_METHOD:
451
452
DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
453
break;
454
455
case PARSEOP_INTEGER:
456
457
DbgPrint (ASL_PARSE_OUTPUT, "INTEGER->%8.8X%8.8X",
458
ACPI_FORMAT_UINT64 (Value));
459
break;
460
461
default:
462
break;
463
}
464
465
DbgPrint (ASL_PARSE_OUTPUT, "\n\n");
466
return (Op);
467
}
468
469
470
/*******************************************************************************
471
*
472
* FUNCTION: TrCreateTargetOp
473
*
474
* PARAMETERS: OriginalOp - Op to be copied
475
*
476
* RETURN: Pointer to the new op. Aborts on allocation failure
477
*
478
* DESCRIPTION: Copy an existing op (and subtree). Used in ASL+ (C-style)
479
* expressions where the target is the same as one of the
480
* operands. A new op and subtree must be created from the
481
* original so that the parse tree can be linked properly.
482
*
483
* NOTE: This code is specific to target operands that are the last
484
* operand in an ASL/AML operator. Meaning that the top-level
485
* parse Op in a possible subtree has a NULL Next pointer.
486
* This simplifies the recursion.
487
*
488
* Subtree example:
489
* DeRefOf (Local1) += 32
490
*
491
* This gets converted to:
492
* Add (DeRefOf (Local1), 32, DeRefOf (Local1))
493
*
494
* Each DeRefOf has a single child, Local1. Even more complex
495
* subtrees can be created via the Index and DeRefOf operators.
496
*
497
******************************************************************************/
498
499
ACPI_PARSE_OBJECT *
500
TrCreateTargetOp (
501
ACPI_PARSE_OBJECT *OriginalOp,
502
ACPI_PARSE_OBJECT *ParentOp)
503
{
504
ACPI_PARSE_OBJECT *Op;
505
506
507
if (!OriginalOp)
508
{
509
return (NULL);
510
}
511
512
Op = UtParseOpCacheCalloc ();
513
514
/* Copy the pertinent values (omit link pointer fields) */
515
516
Op->Asl.Value = OriginalOp->Asl.Value;
517
Op->Asl.Filename = OriginalOp->Asl.Filename;
518
Op->Asl.LineNumber = OriginalOp->Asl.LineNumber;
519
Op->Asl.LogicalLineNumber = OriginalOp->Asl.LogicalLineNumber;
520
Op->Asl.LogicalByteOffset = OriginalOp->Asl.LogicalByteOffset;
521
Op->Asl.Column = OriginalOp->Asl.Column;
522
Op->Asl.Flags = OriginalOp->Asl.Flags;
523
Op->Asl.CompileFlags = OriginalOp->Asl.CompileFlags;
524
Op->Asl.AmlOpcode = OriginalOp->Asl.AmlOpcode;
525
Op->Asl.ParseOpcode = OriginalOp->Asl.ParseOpcode;
526
Op->Asl.Parent = ParentOp;
527
528
UtSetParseOpName (Op);
529
530
/* Copy a possible subtree below this op */
531
532
if (OriginalOp->Asl.Child)
533
{
534
Op->Asl.Child = TrCreateTargetOp (OriginalOp->Asl.Child, Op);
535
}
536
537
if (OriginalOp->Asl.Next) /* Null for top-level op */
538
{
539
Op->Asl.Next = TrCreateTargetOp (OriginalOp->Asl.Next, ParentOp);
540
}
541
542
return (Op);
543
}
544
545
546
/*******************************************************************************
547
*
548
* FUNCTION: TrCreateAssignmentOp
549
*
550
* PARAMETERS: Target - Assignment target
551
* Source - Assignment source
552
*
553
* RETURN: Pointer to the new op. Aborts on allocation failure
554
*
555
* DESCRIPTION: Implements the C-style '=' operator. It changes the parse
556
* tree if possible to utilize the last argument of the math
557
* operators which is a target operand -- thus saving invocation
558
* of and additional Store() operator. An optimization.
559
*
560
******************************************************************************/
561
562
ACPI_PARSE_OBJECT *
563
TrCreateAssignmentOp (
564
ACPI_PARSE_OBJECT *Target,
565
ACPI_PARSE_OBJECT *Source)
566
{
567
ACPI_PARSE_OBJECT *TargetOp;
568
ACPI_PARSE_OBJECT *SourceOp1;
569
ACPI_PARSE_OBJECT *SourceOp2;
570
ACPI_PARSE_OBJECT *Operator;
571
572
573
DbgPrint (ASL_PARSE_OUTPUT,
574
"\nTrCreateAssignmentOp Line [%u to %u] Source %s Target %s\n",
575
Source->Asl.LineNumber, Source->Asl.EndLine,
576
UtGetOpName (Source->Asl.ParseOpcode),
577
UtGetOpName (Target->Asl.ParseOpcode));
578
579
TrSetOpFlags (Target, OP_IS_TARGET);
580
581
switch (Source->Asl.ParseOpcode)
582
{
583
/*
584
* Only these operators can be optimized because they have
585
* a target operand
586
*/
587
case PARSEOP_ADD:
588
case PARSEOP_AND:
589
case PARSEOP_DIVIDE:
590
case PARSEOP_INDEX:
591
case PARSEOP_MOD:
592
case PARSEOP_MULTIPLY:
593
case PARSEOP_NOT:
594
case PARSEOP_OR:
595
case PARSEOP_SHIFTLEFT:
596
case PARSEOP_SHIFTRIGHT:
597
case PARSEOP_SUBTRACT:
598
case PARSEOP_XOR:
599
600
break;
601
602
/* Otherwise, just create a normal Store operator */
603
604
default:
605
goto CannotOptimize;
606
}
607
608
/*
609
* Transform the parse tree such that the target is moved to the
610
* last operand of the operator
611
*/
612
SourceOp1 = Source->Asl.Child;
613
SourceOp2 = SourceOp1->Asl.Next;
614
615
/* NOT only has one operand, but has a target */
616
617
if (Source->Asl.ParseOpcode == PARSEOP_NOT)
618
{
619
SourceOp2 = SourceOp1;
620
}
621
622
/* DIVIDE has an extra target operand (remainder) */
623
624
if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE)
625
{
626
SourceOp2 = SourceOp2->Asl.Next;
627
}
628
629
TargetOp = SourceOp2->Asl.Next;
630
631
/*
632
* Can't perform this optimization if there already is a target
633
* for the operator (ZERO is a "no target" placeholder).
634
*/
635
if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO)
636
{
637
goto CannotOptimize;
638
}
639
640
/* Link in the target as the final operand */
641
642
SourceOp2->Asl.Next = Target;
643
Target->Asl.Parent = Source;
644
return (Source);
645
646
647
CannotOptimize:
648
649
Operator = TrAllocateOp (PARSEOP_STORE);
650
TrLinkOpChildren (Operator, 2, Source, Target);
651
652
/* Set the appropriate line numbers for the new op */
653
654
Operator->Asl.LineNumber = Target->Asl.LineNumber;
655
Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber;
656
Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset;
657
Operator->Asl.Column = Target->Asl.Column;
658
659
return (Operator);
660
}
661
662
663
/*******************************************************************************
664
*
665
* FUNCTION: TrCreateNullTargetOp
666
*
667
* PARAMETERS: None
668
*
669
* RETURN: Pointer to the new op. Aborts on allocation failure
670
*
671
* DESCRIPTION: Create a "null" target op. This is defined by the ACPI
672
* specification to be a zero AML opcode, and indicates that
673
* no target has been specified for the parent operation
674
*
675
******************************************************************************/
676
677
ACPI_PARSE_OBJECT *
678
TrCreateNullTargetOp (
679
void)
680
{
681
ACPI_PARSE_OBJECT *Op;
682
683
684
Op = TrAllocateOp (PARSEOP_ZERO);
685
Op->Asl.CompileFlags |= (OP_IS_TARGET | OP_COMPILE_TIME_CONST);
686
687
DbgPrint (ASL_PARSE_OUTPUT,
688
"\nCreateNullTargetOp Ln/Col %u/%u NewOp %p Op %s\n",
689
Op->Asl.LineNumber, Op->Asl.Column, Op,
690
UtGetOpName (Op->Asl.ParseOpcode));
691
692
return (Op);
693
}
694
695
696
/*******************************************************************************
697
*
698
* FUNCTION: TrCreateConstantLeafOp
699
*
700
* PARAMETERS: ParseOpcode - The constant opcode
701
*
702
* RETURN: Pointer to the new op. Aborts on allocation failure
703
*
704
* DESCRIPTION: Create a leaf op (no children or peers) for one of the
705
* special constants - __LINE__, __FILE__, and __DATE__.
706
*
707
* Note: The fullimplemenation of __METHOD__ cannot happen here because we
708
* don't have a full parse tree at this time and cannot find the parent
709
* control method. __METHOD__ must be implemented later, after the parse
710
* tree has been fully constructed.
711
*
712
******************************************************************************/
713
714
ACPI_PARSE_OBJECT *
715
TrCreateConstantLeafOp (
716
UINT32 ParseOpcode)
717
{
718
ACPI_PARSE_OBJECT *Op = NULL;
719
time_t CurrentTime;
720
char *StaticTimeString;
721
char *TimeString;
722
char *Filename = NULL;
723
ACPI_STATUS Status;
724
725
726
switch (ParseOpcode)
727
{
728
case PARSEOP___LINE__:
729
730
Op = TrAllocateOp (PARSEOP_INTEGER);
731
Op->Asl.Value.Integer = Op->Asl.LineNumber;
732
break;
733
734
case PARSEOP___METHOD__:
735
736
/* Will become a string literal later */
737
738
Op = TrAllocateOp (PARSEOP___METHOD__);
739
Op->Asl.Value.String = NULL;
740
break;
741
742
case PARSEOP___PATH__:
743
744
Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
745
746
/* Op.Asl.Filename contains the full pathname to the file */
747
748
Op->Asl.Value.String = Op->Asl.Filename;
749
break;
750
751
case PARSEOP___FILE__:
752
753
Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
754
755
/* Get the simple filename from the full path */
756
757
Status = FlSplitInputPathname (Op->Asl.Filename, NULL, &Filename);
758
if (ACPI_FAILURE (Status))
759
{
760
return (NULL);
761
}
762
763
Op->Asl.Value.String = Filename;
764
break;
765
766
case PARSEOP___DATE__:
767
768
Op = TrAllocateOp (PARSEOP_STRING_LITERAL);
769
770
/* Get a copy of the current time */
771
772
Op->Asl.Value.String = "";
773
CurrentTime = time (NULL);
774
775
StaticTimeString = ctime (&CurrentTime);
776
if (StaticTimeString)
777
{
778
TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
779
strcpy (TimeString, StaticTimeString);
780
781
TimeString[strlen(TimeString) -1] = 0; /* Remove trailing newline */
782
Op->Asl.Value.String = TimeString;
783
}
784
break;
785
786
default: /* This would be an internal error */
787
788
return (NULL);
789
}
790
791
DbgPrint (ASL_PARSE_OUTPUT,
792
"\nCreateConstantLeafOp Ln/Col %u/%u NewOp %p "
793
"Op %s Value %8.8X%8.8X\n",
794
Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
795
ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
796
797
return (Op);
798
}
799
800
801
/*******************************************************************************
802
*
803
* FUNCTION: TrAllocateOp
804
*
805
* PARAMETERS: ParseOpcode - Opcode to be assigned to the op
806
*
807
* RETURN: New parse op. Aborts on allocation failure
808
*
809
* DESCRIPTION: Allocate and initialize a new parse op for the parse tree
810
*
811
******************************************************************************/
812
813
ACPI_PARSE_OBJECT *
814
TrAllocateOp (
815
UINT32 ParseOpcode)
816
{
817
ACPI_PARSE_OBJECT *Op;
818
ACPI_PARSE_OBJECT *LatestOp;
819
820
ACPI_FUNCTION_NAME (TrAllocateOp);
821
822
823
Op = UtParseOpCacheCalloc ();
824
825
Op->Asl.ParseOpcode = (UINT16) ParseOpcode;
826
Op->Asl.Filename = AslGbl_Files[ASL_FILE_INPUT].Filename;
827
Op->Asl.LineNumber = AslGbl_CurrentLineNumber;
828
Op->Asl.LogicalLineNumber = AslGbl_LogicalLineNumber;
829
Op->Asl.LogicalByteOffset = AslGbl_CurrentLineOffset;
830
Op->Asl.Column = AslGbl_CurrentColumn;
831
832
UtSetParseOpName (Op);
833
834
/* The following is for capturing comments */
835
836
if (AcpiGbl_CaptureComments)
837
{
838
LatestOp = AslGbl_CommentState.LatestParseOp;
839
Op->Asl.InlineComment = NULL;
840
Op->Asl.EndNodeComment = NULL;
841
Op->Asl.CommentList = NULL;
842
Op->Asl.FileChanged = FALSE;
843
844
/*
845
* Check to see if the file name has changed before resetting the
846
* latest parse op.
847
*/
848
if (LatestOp &&
849
(ParseOpcode != PARSEOP_INCLUDE) &&
850
(ParseOpcode != PARSEOP_INCLUDE_END) &&
851
strcmp (LatestOp->Asl.Filename, Op->Asl.Filename))
852
{
853
CvDbgPrint ("latest op: %s\n", LatestOp->Asl.ParseOpName);
854
Op->Asl.FileChanged = TRUE;
855
if (AslGbl_IncludeFileStack)
856
{
857
Op->Asl.ParentFilename = AslGbl_IncludeFileStack->Filename;
858
}
859
else
860
{
861
Op->Asl.ParentFilename = NULL;
862
}
863
}
864
865
AslGbl_CommentState.LatestParseOp = Op;
866
CvDbgPrint ("%s=Set latest parse op to this op.\n", ACPI_GET_FUNCTION_NAME);
867
CvDbgPrint (" Op->Asl.ParseOpName = %s\n",
868
AslGbl_CommentState.LatestParseOp->Asl.ParseOpName);
869
CvDbgPrint (" Op->Asl.ParseOpcode = 0x%x\n", ParseOpcode);
870
871
if (Op->Asl.FileChanged)
872
{
873
CvDbgPrint(" file has been changed!\n");
874
}
875
876
/*
877
* if this parse op's syntax uses () and {} (i.e. Package(1){0x00}) then
878
* set a flag in the comment state. This facilitates paring comments for
879
* these types of opcodes.
880
*/
881
if ((CvParseOpBlockType(Op) == (BLOCK_PAREN | BLOCK_BRACE)) &&
882
(ParseOpcode != PARSEOP_DEFINITION_BLOCK))
883
{
884
CvDbgPrint ("Parsing paren/Brace op now!\n");
885
AslGbl_CommentState.ParsingParenBraceNode = Op;
886
}
887
888
if (AslGbl_CommentListHead)
889
{
890
CvDbgPrint ("Transferring...\n");
891
Op->Asl.CommentList = AslGbl_CommentListHead;
892
AslGbl_CommentListHead = NULL;
893
AslGbl_CommentListTail = NULL;
894
CvDbgPrint (" Transferred current comment list to this op.\n");
895
CvDbgPrint (" %s\n", Op->Asl.CommentList->Comment);
896
}
897
898
if (AslGbl_InlineCommentBuffer)
899
{
900
Op->Asl.InlineComment = AslGbl_InlineCommentBuffer;
901
AslGbl_InlineCommentBuffer = NULL;
902
CvDbgPrint ("Transferred current inline comment list to this op.\n");
903
}
904
}
905
906
return (Op);
907
}
908
909
910
/*******************************************************************************
911
*
912
* FUNCTION: TrPrintOpFlags
913
*
914
* PARAMETERS: Flags - Flags word to be decoded
915
* OutputLevel - Debug output level: ASL_TREE_OUTPUT etc.
916
*
917
* RETURN: None
918
*
919
* DESCRIPTION: Decode a flags word to text. Displays all flags that are set.
920
*
921
******************************************************************************/
922
923
void
924
TrPrintOpFlags (
925
UINT32 Flags,
926
UINT32 OutputLevel)
927
{
928
UINT32 FlagBit = 1;
929
UINT32 i;
930
931
932
for (i = 0; i < ACPI_NUM_OP_FLAGS; i++)
933
{
934
if (Flags & FlagBit)
935
{
936
DbgPrint (OutputLevel, " %s", AslGbl_OpFlagNames[i]);
937
}
938
939
FlagBit <<= 1;
940
}
941
}
942
943