1 2 /****************************************************************************** 3 * 4 * Module Name: aslfold - Constant folding 5 * $Revision: 7 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2003, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 119 #include "aslcompiler.h" 120 #include "aslcompiler.y.h" 121 #include "amlcode.h" 122 123 #include "acdispat.h" 124 #include "acparser.h" 125 126 #define _COMPONENT ACPI_COMPILER 127 ACPI_MODULE_NAME ("aslfold") 128 129 130 /******************************************************************************* 131 * 132 * FUNCTION: OpcAmlEvaluationWalk1 133 * 134 * PARAMETERS: ASL_WALK_CALLBACK 135 * 136 * RETURN: Status 137 * 138 * DESCRIPTION: Descending callback for AML execution of constant subtrees 139 * 140 ******************************************************************************/ 141 142 ACPI_STATUS 143 OpcAmlEvaluationWalk1 ( 144 ACPI_PARSE_OBJECT *Op, 145 UINT32 Level, 146 void *Context) 147 { 148 ACPI_WALK_STATE *WalkState = Context; 149 ACPI_STATUS Status; 150 ACPI_PARSE_OBJECT *OutOp; 151 152 153 WalkState->Op = Op; 154 WalkState->Opcode = Op->Common.AmlOpcode; 155 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 156 157 /* Copy child pointer to Arg for compatibility with Interpreter */ 158 159 if (Op->Asl.Child) 160 { 161 Op->Common.Value.Arg = Op->Asl.Child; 162 } 163 164 /* Call AML dispatcher */ 165 166 Status = AcpiDsExecBeginOp (WalkState, &OutOp); 167 if (ACPI_FAILURE (Status)) 168 { 169 AcpiOsPrintf ("Constant interpretation failed - %s\n", 170 AcpiFormatException (Status)); 171 } 172 173 return (Status); 174 } 175 176 177 /******************************************************************************* 178 * 179 * FUNCTION: OpcAmlEvaluationWalk2 180 * 181 * PARAMETERS: ASL_WALK_CALLBACK 182 * 183 * RETURN: Status 184 * 185 * DESCRIPTION: Ascending callback for AML execution of constant subtrees 186 * 187 ******************************************************************************/ 188 189 ACPI_STATUS 190 OpcAmlEvaluationWalk2 ( 191 ACPI_PARSE_OBJECT *Op, 192 UINT32 Level, 193 void *Context) 194 { 195 ACPI_WALK_STATE *WalkState = Context; 196 ACPI_STATUS Status; 197 198 199 WalkState->Op = Op; 200 WalkState->Opcode = Op->Common.AmlOpcode; 201 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 202 203 /* Copy child pointer to Arg for compatibility with Interpreter */ 204 205 if (Op->Asl.Child) 206 { 207 Op->Common.Value.Arg = Op->Asl.Child; 208 } 209 210 /* Call AML dispatcher */ 211 212 Status = AcpiDsExecEndOp (WalkState); 213 if (ACPI_FAILURE (Status)) 214 { 215 AcpiOsPrintf ("Constant interpretation failed - %s\n", 216 AcpiFormatException (Status)); 217 } 218 219 return (Status); 220 } 221 222 223 /******************************************************************************* 224 * 225 * FUNCTION: OpcAmlCheckForConstant 226 * 227 * PARAMETERS: ASL_WALK_CALLBACK 228 * 229 * RETURN: Status 230 * 231 * DESCRIPTION: Check one Op for a type 3/4/5 AML opcode 232 * 233 ******************************************************************************/ 234 235 ACPI_STATUS 236 OpcAmlCheckForConstant ( 237 ACPI_PARSE_OBJECT *Op, 238 UINT32 Level, 239 void *Context) 240 { 241 ACPI_WALK_STATE *WalkState = Context; 242 243 244 WalkState->Op = Op; 245 WalkState->Opcode = Op->Common.AmlOpcode; 246 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 247 248 DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ", 249 Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName); 250 251 if (!(WalkState->OpInfo->Flags & AML_CONSTANT)) 252 { 253 /* The opcode is not a Type 3/4/5 opcode */ 254 255 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 256 { 257 DbgPrint (ASL_PARSE_OUTPUT, "**** Valid Target, cannot reduce ****\n"); 258 } 259 else 260 { 261 DbgPrint (ASL_PARSE_OUTPUT, "**** Not a Type 3/4/5 opcode ****\n"); 262 } 263 264 if (WalkState->WalkType == ACPI_WALK_CONST_OPTIONAL) 265 { 266 /* 267 * We are looking at at normal expression to see if it can be 268 * reduced. It can't. No error 269 */ 270 return (AE_TYPE); 271 } 272 273 /* 274 * This is an expression that MUST reduce to a constant, and it 275 * can't be reduced. This is an error 276 */ 277 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 278 { 279 AslError (ASL_ERROR, ASL_MSG_INVALID_TARGET, Op, Op->Asl.ParseOpName); 280 } 281 else 282 { 283 AslError (ASL_ERROR, ASL_MSG_INVALID_CONSTANT_OP, Op, Op->Asl.ParseOpName); 284 } 285 286 return (AE_TYPE); 287 } 288 289 /* Debug output */ 290 291 DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345"); 292 293 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 294 { 295 DbgPrint (ASL_PARSE_OUTPUT, " TARGET"); 296 } 297 if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG) 298 { 299 DbgPrint (ASL_PARSE_OUTPUT, " TERMARG"); 300 } 301 DbgPrint (ASL_PARSE_OUTPUT, "\n"); 302 303 return (AE_OK); 304 } 305 306 307 /******************************************************************************* 308 * 309 * FUNCTION: OpcAmlConstantWalk 310 * 311 * PARAMETERS: ASL_WALK_CALLBACK 312 * 313 * RETURN: Status 314 * 315 * DESCRIPTION: Reduce an Op and its subtree to a constant if possible 316 * 317 ******************************************************************************/ 318 319 ACPI_STATUS 320 OpcAmlConstantWalk ( 321 ACPI_PARSE_OBJECT *Op, 322 UINT32 Level, 323 void *Context) 324 { 325 ACPI_WALK_STATE *WalkState; 326 ACPI_STATUS Status = AE_OK; 327 ACPI_OPERAND_OBJECT *ObjDesc; 328 ACPI_PARSE_OBJECT *RootOp; 329 ACPI_PARSE_OBJECT *OriginalParentOp; 330 UINT8 WalkType; 331 332 333 /* 334 * Only interested in subtrees that could possibly contain 335 * expressions that can be evaluated at this time 336 */ 337 if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) || 338 (Op->Asl.CompileFlags & NODE_IS_TARGET)) 339 { 340 return (AE_OK); 341 } 342 343 /* 344 * Set the walk type based on the reduction used for this op 345 */ 346 if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG) 347 { 348 /* Op is a TermArg, constant folding is merely optional */ 349 350 if (!Gbl_FoldConstants) 351 { 352 return (AE_CTRL_DEPTH); 353 } 354 355 WalkType = ACPI_WALK_CONST_OPTIONAL; 356 } 357 else 358 { 359 /* Op is a DataObject, the expression MUST reduced to a constant */ 360 361 WalkType = ACPI_WALK_CONST_REQUIRED; 362 } 363 364 /* Create a new walk state */ 365 366 WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 367 if (!WalkState) 368 { 369 return AE_NO_MEMORY; 370 } 371 372 WalkState->NextOp = NULL; 373 WalkState->Params = NULL; 374 WalkState->CallerReturnDesc = &ObjDesc; 375 WalkState->WalkType = WalkType; 376 377 /* Examine the entire subtree -- all nodes must be constants or type 3/4/5 opcodes */ 378 379 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD, 380 OpcAmlCheckForConstant, NULL, WalkState); 381 382 /* 383 * Did we find an entire subtree that contains all constants and type 3/4/5 384 * opcodes? (Only AE_OK or AE_TYPE returned from above) 385 */ 386 if (Status == AE_TYPE) 387 { 388 /* Subtree cannot be reduced to a constant */ 389 390 if (WalkState->WalkType == ACPI_WALK_CONST_OPTIONAL) 391 { 392 AcpiDsDeleteWalkState (WalkState); 393 return (AE_OK); 394 } 395 396 /* Don't descend any further, and use a default "constant" value */ 397 398 Status = AE_CTRL_DEPTH; 399 } 400 else 401 { 402 /* Subtree can be reduced */ 403 404 /* Allocate a new temporary root for this subtree */ 405 406 RootOp = TrAllocateNode (PARSEOP_INTEGER); 407 if (!RootOp) 408 { 409 return (AE_NO_MEMORY); 410 } 411 412 RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP; 413 414 OriginalParentOp = Op->Common.Parent; 415 Op->Common.Parent = RootOp; 416 417 /* 418 * Hand off the subtree to the AML interpreter 419 */ 420 Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE, OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState); 421 Op->Common.Parent = OriginalParentOp; 422 423 /* TBD: we really *should* release the RootOp node */ 424 425 if (ACPI_SUCCESS (Status)) 426 { 427 TotalFolds++; 428 429 /* Get the final result */ 430 431 Status = AcpiDsResultPop (&ObjDesc, WalkState); 432 } 433 } 434 435 if (ACPI_FAILURE (Status)) 436 { 437 /* We could not resolve the subtree for some reason */ 438 439 AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op, Op->Asl.ParseOpName); 440 441 /* Set the subtree value to ZERO anyway. Eliminates further errors */ 442 443 Op->Asl.ParseOpcode = PARSEOP_INTEGER; 444 Op->Common.Value.Integer = 0; 445 OpcSetOptimalIntegerSize (Op); 446 } 447 else 448 { 449 AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op, Op->Asl.ParseOpName); 450 451 /* 452 * Because we know we executed type 3/4/5 opcodes above, we know that 453 * the result must be either an Integer, String, or Buffer. 454 */ 455 switch (ACPI_GET_OBJECT_TYPE (ObjDesc)) 456 { 457 case ACPI_TYPE_INTEGER: 458 459 Op->Asl.ParseOpcode = PARSEOP_INTEGER; 460 Op->Common.Value.Integer = ObjDesc->Integer.Value; 461 OpcSetOptimalIntegerSize (Op); 462 463 DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (INTEGER) %8.8X%8.8X\n", 464 ACPI_HIDWORD (ObjDesc->Integer.Value), 465 ACPI_LODWORD (ObjDesc->Integer.Value)); 466 break; 467 468 469 case ACPI_TYPE_STRING: 470 471 Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL; 472 Op->Common.AmlOpcode = AML_STRING_OP; 473 Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1; 474 Op->Common.Value.String = ObjDesc->String.Pointer; 475 476 DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (STRING) %s\n", 477 Op->Common.Value.String); 478 479 break; 480 481 482 case ACPI_TYPE_BUFFER: 483 484 Op->Asl.ParseOpcode = PARSEOP_BUFFER; 485 Op->Common.AmlOpcode = AML_BUFFER_OP; 486 UtSetParseOpName (Op); 487 488 /* Child node is the buffer length */ 489 490 RootOp = TrAllocateNode (PARSEOP_INTEGER); 491 492 RootOp->Asl.AmlOpcode = AML_DWORD_OP; 493 RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length; 494 RootOp->Asl.Parent = Op; 495 496 (void) OpcSetOptimalIntegerSize (RootOp); 497 498 Op->Asl.Child = RootOp; 499 Op = RootOp; 500 UtSetParseOpName (Op); 501 502 /* Peer to the child is the raw buffer data */ 503 504 RootOp = TrAllocateNode (PARSEOP_RAW_DATA); 505 RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER; 506 RootOp->Asl.AmlLength = ObjDesc->Buffer.Length; 507 RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer; 508 RootOp->Asl.Parent = Op->Asl.Parent; 509 510 Op->Asl.Next = RootOp; 511 Op = RootOp; 512 513 DbgPrint (ASL_PARSE_OUTPUT, "Constant expression reduced to (BUFFER) length %X\n", 514 ObjDesc->Buffer.Length); 515 break; 516 517 518 default: 519 printf ("Unsupported return type: %s\n", 520 AcpiUtGetObjectTypeName (ObjDesc)); 521 break; 522 } 523 } 524 525 UtSetParseOpName (Op); 526 Op->Asl.Child = NULL; 527 528 AcpiDsDeleteWalkState (WalkState); 529 530 return (AE_CTRL_DEPTH); 531 } 532 533