diff options
| author | Jung-uk Kim <jkim@FreeBSD.org> | 2014-11-10 21:30:04 +0000 | 
|---|---|---|
| committer | Jung-uk Kim <jkim@FreeBSD.org> | 2014-11-10 21:30:04 +0000 | 
| commit | e8991236d498c9646c20a8acf0236cf3342dad6f (patch) | |
| tree | b4bd3052883fca1145eaa389311d46371584f6d9 /source/compiler | |
| parent | d4e301bc21b6911ed7f5d6a86659c4882fa7ab55 (diff) | |
Notes
Diffstat (limited to 'source/compiler')
28 files changed, 2126 insertions, 45 deletions
diff --git a/source/compiler/aslbtypes.c b/source/compiler/aslbtypes.c index 025a416705eba..288678a65f6dd 100644 --- a/source/compiler/aslbtypes.c +++ b/source/compiler/aslbtypes.c @@ -374,6 +374,12 @@ AnGetBtype (      UINT32                  ThisNodeBtype = 0; +    if (!Op) +    { +        AcpiOsPrintf ("Null Op in AnGetBtype\n"); +        return (ACPI_UINT32_MAX); +    } +      if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)     ||          (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||          (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) diff --git a/source/compiler/aslcodegen.c b/source/compiler/aslcodegen.c index 8cef7555b1346..a6a866e02ed04 100644 --- a/source/compiler/aslcodegen.c +++ b/source/compiler/aslcodegen.c @@ -107,6 +107,12 @@ CgGenerateAmlOutput (      TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD,          CgAmlWriteWalk, NULL, NULL); + +    DbgPrint (ASL_TREE_OUTPUT, +        "%*s Value    P_Op A_Op OpLen PByts Len  SubLen PSubLen OpPtr" +        "    Parent   Child    Next     Flags    AcTyp    Final Col L\n", +        76, " "); +      CgCloseTable ();  } @@ -138,7 +144,8 @@ CgAmlWriteWalk (          DbgPrint (ASL_TREE_OUTPUT,              "Final parse tree used for AML output:\n");          DbgPrint (ASL_TREE_OUTPUT, -            "%*s Value    P_Op A_Op OpLen PByts Len  SubLen PSubLen OpPtr    Child    Parent   Flags    AcTyp    Final Col L\n", +            "%*s Value    P_Op A_Op OpLen PByts Len  SubLen PSubLen OpPtr" +            "    Parent   Child    Next     Flags    AcTyp    Final Col L\n",              76, " ");      } @@ -161,7 +168,8 @@ CgAmlWriteWalk (      }      DbgPrint (ASL_TREE_OUTPUT, -    "%08X %04X %04X %01X     %04X  %04X %04X   %04X    %08X %08X %08X %08X %08X %04X  %02d  %02d\n", +    "%08X %04X %04X %01X     %04X  %04X %04X   %04X    " +    "%08X %08X %08X %08X %08X %08X %04X  %02d  %02d\n",              /* 1  */ (UINT32) Op->Asl.Value.Integer,              /* 2  */ Op->Asl.ParseOpcode,              /* 3  */ Op->Asl.AmlOpcode, @@ -171,13 +179,14 @@ CgAmlWriteWalk (              /* 7  */ Op->Asl.AmlSubtreeLength,              /* 8  */ Op->Asl.Parent ? Op->Asl.Parent->Asl.AmlSubtreeLength : 0,              /* 9  */ Op, -            /* 10 */ Op->Asl.Child, -            /* 11 */ Op->Asl.Parent, -            /* 12 */ Op->Asl.CompileFlags, -            /* 13 */ Op->Asl.AcpiBtype, -            /* 14 */ Op->Asl.FinalAmlLength, -            /* 15 */ Op->Asl.Column, -            /* 16 */ Op->Asl.LineNumber); +            /* 10 */ Op->Asl.Parent, +            /* 11 */ Op->Asl.Child, +            /* 12 */ Op->Asl.Next, +            /* 13 */ Op->Asl.CompileFlags, +            /* 14 */ Op->Asl.AcpiBtype, +            /* 15 */ Op->Asl.FinalAmlLength, +            /* 16 */ Op->Asl.Column, +            /* 17 */ Op->Asl.LineNumber);      /* Generate the AML for this node */ diff --git a/source/compiler/aslcompile.c b/source/compiler/aslcompile.c index 62d7d87043295..432ec8b7f9e06 100644 --- a/source/compiler/aslcompile.c +++ b/source/compiler/aslcompile.c @@ -147,6 +147,13 @@ CmDoCompile (      Event = UtBeginEvent ("Flush source input");      CmFlushSourceCode (); +    /* Prune the parse tree if requested (debug purposes only) */ + +    if (Gbl_PruneParseTree) +    { +        AslPruneParseTree (Gbl_PruneDepth, Gbl_PruneType); +    } +      /* Optional parse tree dump, compiler debug output only */      LsDumpParseTree (); diff --git a/source/compiler/aslcompiler.h b/source/compiler/aslcompiler.h index fdf19c1840d72..72d4699c9b951 100644 --- a/source/compiler/aslcompiler.h +++ b/source/compiler/aslcompiler.h @@ -543,6 +543,27 @@ OptOptimizeNamePath (  /* + * aslprintf - Printf/Fprintf macros + */ +void +OpcDoPrintf ( +    ACPI_PARSE_OBJECT       *Op); + +void +OpcDoFprintf ( +    ACPI_PARSE_OBJECT       *Op); + + +/* + * aslprune - parse tree pruner + */ +void +AslPruneParseTree ( +    UINT32                  PruneDepth, +    UINT32                  Type); + + +/*   * aslcodegen - code generation   */  void @@ -684,6 +705,16 @@ TrCreateLeafNode (      UINT32                  ParseOpcode);  ACPI_PARSE_OBJECT * +TrCreateAssignmentNode ( +    ACPI_PARSE_OBJECT       *Target, +    ACPI_PARSE_OBJECT       *Source); + +ACPI_PARSE_OBJECT * +TrCreateTargetOperand ( +    ACPI_PARSE_OBJECT       *OriginalOp, +    ACPI_PARSE_OBJECT       *ParentOp); + +ACPI_PARSE_OBJECT *  TrCreateValuedLeafNode (      UINT32                  ParseOpcode,      UINT64                  Value); diff --git a/source/compiler/aslcompiler.l b/source/compiler/aslcompiler.l index 523241a5a5579..c26408fc363c7 100644 --- a/source/compiler/aslcompiler.l +++ b/source/compiler/aslcompiler.l @@ -117,7 +117,49 @@ NamePathTail                [.]{NameSeg}                                else {yyterminate ();} }  ";"                         { count (0); return(';'); } - +    /* ASL Extension: Standard C operators */ + +"~"                         { count (3); return (PARSEOP_EXP_NOT); } +"!"                         { count (3); return (PARSEOP_EXP_LOGICAL_NOT); } +"*"                         { count (3); return (PARSEOP_EXP_MULTIPLY); } +"/"                         { count (3); return (PARSEOP_EXP_DIVIDE); } +"%"                         { count (3); return (PARSEOP_EXP_MODULO); } +"+"                         { count (3); return (PARSEOP_EXP_ADD); } +"-"                         { count (3); return (PARSEOP_EXP_SUBTRACT); } +">>"                        { count (3); return (PARSEOP_EXP_SHIFT_RIGHT); } +"<<"                        { count (3); return (PARSEOP_EXP_SHIFT_LEFT); } +"<"                         { count (3); return (PARSEOP_EXP_LESS); } +">"                         { count (3); return (PARSEOP_EXP_GREATER); } +"&"                         { count (3); return (PARSEOP_EXP_AND); } +"<="                        { count (3); return (PARSEOP_EXP_LESS_EQUAL); } +">="                        { count (3); return (PARSEOP_EXP_GREATER_EQUAL); } +"=="                        { count (3); return (PARSEOP_EXP_EQUAL); } +"!="                        { count (3); return (PARSEOP_EXP_NOT_EQUAL); } +"|"                         { count (3); return (PARSEOP_EXP_OR); } +"&&"                        { count (3); return (PARSEOP_EXP_LOGICAL_AND); } +"||"                        { count (3); return (PARSEOP_EXP_LOGICAL_OR); } +"++"                        { count (3); return (PARSEOP_EXP_INCREMENT); } +"--"                        { count (3); return (PARSEOP_EXP_DECREMENT); } +"^ "                        { count (3); return (PARSEOP_EXP_XOR); } + +    /* ASL Extension: Standard C assignment operators */ + +"="                         { count (3); return (PARSEOP_EXP_EQUALS); } +"+="                        { count (3); return (PARSEOP_EXP_ADD_EQ); } +"-="                        { count (3); return (PARSEOP_EXP_SUB_EQ); } +"*="                        { count (3); return (PARSEOP_EXP_MUL_EQ); } +"/="                        { count (3); return (PARSEOP_EXP_DIV_EQ); } +"%="                        { count (3); return (PARSEOP_EXP_MOD_EQ); } +"<<="                       { count (3); return (PARSEOP_EXP_SHL_EQ); } +">>="                       { count (3); return (PARSEOP_EXP_SHR_EQ); } +"&="                        { count (3); return (PARSEOP_EXP_AND_EQ); } +"^="                        { count (3); return (PARSEOP_EXP_XOR_EQ); } +"|="                        { count (3); return (PARSEOP_EXP_OR_EQ); } + + +    /* +     * Begin standard ASL grammar +     */  0[xX]{HexDigitChar}+ |  {DigitChar}+                { AslCompilerlval.i = UtDoConstant ((char *) AslCompilertext);                                  count (1); return (PARSEOP_INTEGER); } @@ -592,6 +634,44 @@ NamePathTail                [.]{NameSeg}  "Transfer8_16"              { count (0); return (PARSEOP_XFERTYPE_8_16); }  "Transfer16"                { count (0); return (PARSEOP_XFERTYPE_16); } +    /* ToPld macro */ + +"ToPLD"                     { count (0); return (PARSEOP_TOPLD); } + +"PLD_Revision"              { count (0); return (PARSEOP_PLD_REVISION); } +"PLD_IgnoreColor"           { count (0); return (PARSEOP_PLD_IGNORECOLOR); } +"PLD_Red"                   { count (0); return (PARSEOP_PLD_RED); } +"PLD_Green"                 { count (0); return (PARSEOP_PLD_GREEN); } +"PLD_Blue"                  { count (0); return (PARSEOP_PLD_BLUE); } +"PLD_Width"                 { count (0); return (PARSEOP_PLD_WIDTH); } +"PLD_Height"                { count (0); return (PARSEOP_PLD_HEIGHT); } +"PLD_UserVisible"           { count (0); return (PARSEOP_PLD_USERVISIBLE); } +"PLD_Dock"                  { count (0); return (PARSEOP_PLD_DOCK); } +"PLD_Lid"                   { count (0); return (PARSEOP_PLD_LID); } +"PLD_Panel"                 { count (0); return (PARSEOP_PLD_PANEL); } +"PLD_VerticalPosition"      { count (0); return (PARSEOP_PLD_VERTICALPOSITION); } +"PLD_HorizontalPosition"    { count (0); return (PARSEOP_PLD_HORIZONTALPOSITION); } +"PLD_Shape"                 { count (0); return (PARSEOP_PLD_SHAPE); } +"PLD_GroupOrientation"      { count (0); return (PARSEOP_PLD_GROUPORIENTATION); } +"PLD_GroupToken"            { count (0); return (PARSEOP_PLD_GROUPTOKEN); } +"PLD_GroupPosition"         { count (0); return (PARSEOP_PLD_GROUPPOSITION); } +"PLD_Bay"                   { count (0); return (PARSEOP_PLD_BAY); } +"PLD_Ejectable"             { count (0); return (PARSEOP_PLD_EJECTABLE); } +"PLD_EjectRequired"         { count (0); return (PARSEOP_PLD_EJECTREQUIRED); } +"PLD_CabinetNumber"         { count (0); return (PARSEOP_PLD_CABINETNUMBER); } +"PLD_CardCageNumber"        { count (0); return (PARSEOP_PLD_CARDCAGENUMBER); } +"PLD_Reference"             { count (0); return (PARSEOP_PLD_REFERENCE); } +"PLD_Rotation"              { count (0); return (PARSEOP_PLD_ROTATION); } +"PLD_Order"                 { count (0); return (PARSEOP_PLD_ORDER); } +"PLD_Reserved"              { count (0); return (PARSEOP_PLD_RESERVED); } +"PLD_VerticalOffset"        { count (0); return (PARSEOP_PLD_VERTICALOFFSET); } +"PLD_HorizontalOffset"      { count (0); return (PARSEOP_PLD_HORIZONTALOFFSET); } + + +    /* printf debug macros */ +"printf"                    { count (0); return (PARSEOP_PRINTF); } +"fprintf"                   { count (0); return (PARSEOP_FPRINTF); } +      /* Predefined compiler names */  "__DATE__"                  { count (0); return (PARSEOP___DATE__); } @@ -628,10 +708,6 @@ NamePathTail                [.]{NameSeg}                                  DbgPrint (ASL_PARSE_OUTPUT, "NameString: %s\n", s);                                  return (PARSEOP_NAMESTRING); } -"*" | -"/"                         { count (1); -                                AslCompilererror ("Parse error, expecting ASL keyword or name");} -  .                           { count (1);                                  sprintf (MsgBuffer,                                      "Invalid character (0x%2.2X), expecting ASL keyword or name", diff --git a/source/compiler/asldefine.h b/source/compiler/asldefine.h index 94002816ebcca..2c1319670cdfa 100644 --- a/source/compiler/asldefine.h +++ b/source/compiler/asldefine.h @@ -49,8 +49,8 @@   * Compiler versions and names   */  #define ASL_REVISION                ACPI_CA_VERSION -#define ASL_COMPILER_NAME           "ASL Optimizing Compiler" -#define AML_DISASSEMBLER_NAME       "AML Disassembler" +#define ASL_COMPILER_NAME           "ASL+ Optimizing Compiler" +#define AML_DISASSEMBLER_NAME       "AML/ASL+ Disassembler"  #define ASL_INVOCATION_NAME         "iasl"  #define ASL_CREATOR_ID              "INTL" diff --git a/source/compiler/aslglobal.h b/source/compiler/aslglobal.h index 8106824fd8efb..a3cbb2068302e 100644 --- a/source/compiler/aslglobal.h +++ b/source/compiler/aslglobal.h @@ -173,6 +173,7 @@ ASL_EXTERN BOOLEAN                  ASL_INIT_GLOBAL (Gbl_VerboseTemplates, FALSE  ASL_EXTERN BOOLEAN                  ASL_INIT_GLOBAL (Gbl_DoTemplates, FALSE);  ASL_EXTERN BOOLEAN                  ASL_INIT_GLOBAL (Gbl_CompileGeneric, FALSE);  ASL_EXTERN BOOLEAN                  ASL_INIT_GLOBAL (Gbl_AllExceptionsDisabled, FALSE); +ASL_EXTERN BOOLEAN                  ASL_INIT_GLOBAL (Gbl_PruneParseTree, FALSE);  #define HEX_OUTPUT_NONE             0 @@ -251,6 +252,8 @@ ASL_EXTERN UINT32                   ASL_INIT_GLOBAL (Gbl_NumNamespaceObjects, 0)  ASL_EXTERN UINT32                   ASL_INIT_GLOBAL (Gbl_ReservedMethods, 0);  ASL_EXTERN char                     ASL_INIT_GLOBAL (*Gbl_TableSignature, "NO_SIG");  ASL_EXTERN char                     ASL_INIT_GLOBAL (*Gbl_TableId, "NO_ID"); +ASL_EXTERN UINT8                    ASL_INIT_GLOBAL (Gbl_PruneDepth, 0); +ASL_EXTERN UINT16                   ASL_INIT_GLOBAL (Gbl_PruneType, 0);  /* Static structures */ diff --git a/source/compiler/aslload.c b/source/compiler/aslload.c index 1207f43a3d825..075781ad8f0da 100644 --- a/source/compiler/aslload.c +++ b/source/compiler/aslload.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __ASLLOAD_C__ -  #include "aslcompiler.h"  #include "amlcode.h"  #include "acdispat.h" diff --git a/source/compiler/aslmain.c b/source/compiler/aslmain.c index 1ef7b1cafc8f7..9738fb51186f7 100644 --- a/source/compiler/aslmain.c +++ b/source/compiler/aslmain.c @@ -187,13 +187,17 @@ Usage (      ACPI_OPTION ("-db",             "Do not translate Buffers to Resource Templates");      ACPI_OPTION ("-dc <f1 f2 ...>", "Disassemble AML and immediately compile it");      ACPI_OPTION ("",                "  (Obtain DSDT from current system if no input file)"); +    ACPI_OPTION ("-dl",             "Emit legacy ASL code only (no C-style operators)");      ACPI_OPTION ("-e  <f1 f2 ...>", "Include ACPI table(s) for external symbol resolution");      ACPI_OPTION ("-fe <file>",      "Specify external symbol declaration file");      ACPI_OPTION ("-in",             "Ignore NoOp opcodes");      ACPI_OPTION ("-vt",             "Dump binary table data in hex format within output file");      printf ("\nDebug Options:\n"); -    ACPI_OPTION ("-bf -bt",         "Create debug file (full or parse tree only) (*.txt)"); +    ACPI_OPTION ("-bf",             "Create debug file (full output) (*.txt)"); +    ACPI_OPTION ("-bs",             "Create debug file (parse tree only) (*.txt)"); +    ACPI_OPTION ("-bp <depth>",     "Prune ASL parse tree"); +    ACPI_OPTION ("-bt <type>",      "Object type to be pruned from the parse tree");      ACPI_OPTION ("-f",              "Ignore errors, force creation of AML output file(s)");      ACPI_OPTION ("-m <size>",       "Set internal line buffer size (in Kbytes)");      ACPI_OPTION ("-n",              "Parse only, no output generation"); diff --git a/source/compiler/aslmap.c b/source/compiler/aslmap.c index 84fb24255c12b..3e9f6131efab5 100644 --- a/source/compiler/aslmap.c +++ b/source/compiler/aslmap.c @@ -446,7 +446,38 @@ const ASL_MAPPING_ENTRY     AslKeywordMapping [] =  /* XFERTYPE_16 */               OP_TABLE_ENTRY (AML_BYTE_OP,                2,                              0,                  0),  /* XOR */                       OP_TABLE_ENTRY (AML_BIT_XOR_OP,             0,                              0,                  ACPI_BTYPE_INTEGER),  /* ZERO */                      OP_TABLE_ENTRY (AML_ZERO_OP,                0,                              0,                  ACPI_BTYPE_INTEGER), - +/* TOPLD */                     OP_TABLE_ENTRY (AML_DWORD_OP,               0,                              NODE_AML_PACKAGE,   ACPI_BTYPE_INTEGER), +/* XFERSIZE_128 */              OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* REVISION */                  OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* IGNORECOLOR */               OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* RED */                       OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* GREEN */                     OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* BLUE */                      OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* WIDTH */                     OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* HEIGHT */                    OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* USERVISIBLE */               OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* DOCK */                      OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* LID */                       OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* PANEL */                     OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* VERTICALPOSITION */          OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* HORIZONTALPOSITION */        OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* SHAPE */                     OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* GROUPORIENTATION */          OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* GROUPTOKEN */                OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* GROUPPOSITION */             OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* BAY */                       OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* EJECTABLE */                 OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* EJECTREQUIRED */             OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* CABINETNUMBER */             OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* CARDCAGENUMBER */            OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* REFERENCE */                 OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* ROTATION */                  OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* ORDER */                     OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* RESERVED */                  OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* VERTICALOFFSET */            OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* HORIZONTALOFFSET */          OP_TABLE_ENTRY (AML_BYTE_OP,                0,                              0,                  0), +/* PRINTF */                    OP_TABLE_ENTRY (AML_STORE_OP,               0,                              0,                  ACPI_BTYPE_DATA_REFERENCE), +/* FPRINTF */                   OP_TABLE_ENTRY (AML_STORE_OP,               0,                              0,                  ACPI_BTYPE_DATA_REFERENCE),  /*! [End] no source code translation !*/  }; diff --git a/source/compiler/aslopcodes.c b/source/compiler/aslopcodes.c index 8030c950fa055..c14ff15b82af8 100644 --- a/source/compiler/aslopcodes.c +++ b/source/compiler/aslopcodes.c @@ -68,9 +68,62 @@ OpcDoEisaId (      ACPI_PARSE_OBJECT       *Op);  static void +OpcDoPld ( +    ACPI_PARSE_OBJECT       *Op); + +static void  OpcDoUuId (      ACPI_PARSE_OBJECT       *Op); +static UINT8 * +OpcEncodePldBuffer ( +    ACPI_PLD_INFO           *PldInfo); + + +/* ToPld strings */ + +static char *AslPldPanelList[] = +{ +    "TOP", +    "BOTTOM", +    "LEFT", +    "RIGHT", +    "FRONT", +    "BACK", +    "UNKNOWN", +    NULL +}; + +static char *AslPldVerticalPositionList[] = +{ +    "UPPER", +    "CENTER", +    "LOWER", +    NULL +}; + +static char *AslPldHorizontalPositionList[] = +{ +    "LEFT", +    "CENTER", +    "RIGHT", +    NULL +}; + +static char *AslPldShapeList[] = +{ +    "ROUND", +    "OVAL", +    "SQUARE", +    "VERTICALRECTANGLE", +    "HORIZONTALRECTANGLE", +    "VERTICALTRAPEZOID", +    "HORIZONTALTRAPEZOID", +    "UNKNOWN", +    "CHAMFERED", +    NULL +}; +  /*******************************************************************************   * @@ -653,9 +706,698 @@ OpcDoEisaId (  /*******************************************************************************   * + * FUNCTION:    OpcEncodePldBuffer + * + * PARAMETERS:  PldInfo             - _PLD buffer struct (Using local struct) + * + * RETURN:      Encode _PLD buffer suitable for return value from _PLD + * + * DESCRIPTION: Bit-packs a _PLD buffer struct. + * + ******************************************************************************/ + +static UINT8 * +OpcEncodePldBuffer ( +    ACPI_PLD_INFO           *PldInfo) +{ +    UINT32                  *Buffer; +    UINT32                  Dword; + + +    Buffer = ACPI_ALLOCATE_ZEROED (ACPI_PLD_BUFFER_SIZE); +    if (!Buffer) +    { +        return (NULL); +    } + +    /* First 32 bits */ + +    Dword = 0; +    ACPI_PLD_SET_REVISION       (&Dword, PldInfo->Revision); +    ACPI_PLD_SET_IGNORE_COLOR   (&Dword, PldInfo->IgnoreColor); +    ACPI_PLD_SET_RED            (&Dword, PldInfo->Red); +    ACPI_PLD_SET_GREEN          (&Dword, PldInfo->Green); +    ACPI_PLD_SET_BLUE           (&Dword, PldInfo->Blue); +    ACPI_MOVE_32_TO_32          (&Buffer[0], &Dword); + +    /* Second 32 bits */ + +    Dword = 0; +    ACPI_PLD_SET_WIDTH          (&Dword, PldInfo->Width); +    ACPI_PLD_SET_HEIGHT         (&Dword, PldInfo->Height); +    ACPI_MOVE_32_TO_32          (&Buffer[1], &Dword); + +    /* Third 32 bits */ + +    Dword = 0; +    ACPI_PLD_SET_USER_VISIBLE   (&Dword, PldInfo->UserVisible); +    ACPI_PLD_SET_DOCK           (&Dword, PldInfo->Dock); +    ACPI_PLD_SET_LID            (&Dword, PldInfo->Lid); +    ACPI_PLD_SET_PANEL          (&Dword, PldInfo->Panel); +    ACPI_PLD_SET_VERTICAL       (&Dword, PldInfo->VerticalPosition); +    ACPI_PLD_SET_HORIZONTAL     (&Dword, PldInfo->HorizontalPosition); +    ACPI_PLD_SET_SHAPE          (&Dword, PldInfo->Shape); +    ACPI_PLD_SET_ORIENTATION    (&Dword, PldInfo->GroupOrientation); +    ACPI_PLD_SET_TOKEN          (&Dword, PldInfo->GroupToken); +    ACPI_PLD_SET_POSITION       (&Dword, PldInfo->GroupPosition); +    ACPI_PLD_SET_BAY            (&Dword, PldInfo->Bay); +    ACPI_MOVE_32_TO_32          (&Buffer[2], &Dword); + +    /* Fourth 32 bits */ + +    Dword = 0; +    ACPI_PLD_SET_EJECTABLE      (&Dword, PldInfo->Ejectable); +    ACPI_PLD_SET_OSPM_EJECT     (&Dword, PldInfo->OspmEjectRequired); +    ACPI_PLD_SET_CABINET        (&Dword, PldInfo->CabinetNumber); +    ACPI_PLD_SET_CARD_CAGE      (&Dword, PldInfo->CardCageNumber); +    ACPI_PLD_SET_REFERENCE      (&Dword, PldInfo->Reference); +    ACPI_PLD_SET_ROTATION       (&Dword, PldInfo->Rotation); +    ACPI_PLD_SET_ORDER          (&Dword, PldInfo->Order); +    ACPI_MOVE_32_TO_32          (&Buffer[3], &Dword); + +    if (PldInfo->Revision >= 2) +    { +        /* Fifth 32 bits */ + +        Dword = 0; +        ACPI_PLD_SET_VERT_OFFSET    (&Dword, PldInfo->VerticalOffset); +        ACPI_PLD_SET_HORIZ_OFFSET   (&Dword, PldInfo->HorizontalOffset); +        ACPI_MOVE_32_TO_32          (&Buffer[4], &Dword); +    } + +    return (ACPI_CAST_PTR (UINT8, Buffer)); +} + + +/******************************************************************************* + * + * FUNCTION:    OpcStrupr (strupr) + * + * PARAMETERS:  SrcString           - The source string to convert + * + * RETURN:      None + * + * DESCRIPTION: Convert string to uppercase + * + * NOTE: This is not a POSIX function, so it appears here, not in utclib.c + * + ******************************************************************************/ + +static void +OpcStrupr ( +    char                    *SrcString) +{ +    char                    *String; + + +    if (!SrcString) +    { +        return; +    } + +    /* Walk entire string, uppercasing the letters */ + +    for (String = SrcString; *String; String++) +    { +        *String = (char) toupper ((int) *String); +    } + +    return; +} + + +/******************************************************************************* + * + * FUNCTION:    OpcFindName + * + * PARAMETERS:  List                - Array of char strings to be searched + *              Name                - Char string to string for + *              Index               - Index value to set if found + * + * RETURN:      TRUE if any names matched, FALSE otherwise + * + * DESCRIPTION: Match PLD name to value in lookup table. Sets Value to + *              equivalent parameter value. + * + ******************************************************************************/ + +static BOOLEAN +OpcFindName ( +    char                    **List, +    char                    *Name, +    UINT64                  *Index) +{ +    char                     *Str; +    UINT32                   i; + + +    OpcStrupr (Name); + +    for (i = 0, Str = List[0]; Str; i++, Str = List[i]) +    { +        if (!(ACPI_STRNCMP (Str, Name, ACPI_STRLEN (Name)))) +        { +            *Index = i; +            return (TRUE); +        } +    } + +    return (FALSE); +} + + +/******************************************************************************* + * + * FUNCTION:    OpcDoPld + * + * PARAMETERS:  Op                  - Parse node + * + * RETURN:      None + * + * DESCRIPTION: Convert ToPLD macro to 20-byte buffer + * + ******************************************************************************/ + +static void +OpcDoPld ( +    ACPI_PARSE_OBJECT       *Op) +{ +    UINT8                   *Buffer; +    ACPI_PARSE_OBJECT       *Node; +    ACPI_PLD_INFO           PldInfo; +    ACPI_PARSE_OBJECT       *NewOp; + + +    if (!Op) +    { +        AslError(ASL_ERROR, ASL_MSG_NOT_EXIST, Op, NULL); +        return; +    } + +    if (Op->Asl.ParseOpcode != PARSEOP_TOPLD) +    { +        AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Op, NULL); +        return; +    } + +    Buffer = UtLocalCalloc (ACPI_PLD_BUFFER_SIZE); +    if (!Buffer) +    { +        AslError(ASL_ERROR, ASL_MSG_BUFFER_ALLOCATION, Op, NULL); +        return; +    } + +    ACPI_MEMSET (&PldInfo, 0, sizeof (ACPI_PLD_INFO)); + +    Node = Op->Asl.Child; +    while (Node) +    { +        switch (Node->Asl.ParseOpcode) +        { +        case PARSEOP_PLD_REVISION: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 127) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            PldInfo.Revision = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_IGNORECOLOR: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 1) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            PldInfo.IgnoreColor = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_RED: +        case PARSEOP_PLD_GREEN: +        case PARSEOP_PLD_BLUE: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 255) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_RED) +            { +                PldInfo.Red = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else if (Node->Asl.ParseOpcode == PARSEOP_PLD_GREEN) +            { +                PldInfo.Green = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else /* PARSEOP_PLD_BLUE */ +            { +                PldInfo.Blue = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            break; + +        case PARSEOP_PLD_WIDTH: +        case PARSEOP_PLD_HEIGHT: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 65535) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_WIDTH) +            { +                PldInfo.Width = (UINT16) Node->Asl.Child->Asl.Value.Integer; +            } +            else /* PARSEOP_PLD_HEIGHT */ +            { +                PldInfo.Height = (UINT16) Node->Asl.Child->Asl.Value.Integer; +            } + +            break; + +        case PARSEOP_PLD_USERVISIBLE: +        case PARSEOP_PLD_DOCK: +        case PARSEOP_PLD_LID: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 1) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_USERVISIBLE) +            { +                PldInfo.UserVisible = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else if (Node->Asl.ParseOpcode == PARSEOP_PLD_DOCK) +            { +                PldInfo.Dock = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else +            { +                PldInfo.Lid = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } + +            break; + +        case PARSEOP_PLD_PANEL: + +            if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) +            { +                if (Node->Asl.Child->Asl.Value.Integer > 6) +                { +                    AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                    break; +                } +            } +            else /* PARSEOP_STRING */ +            { +                if (!OpcFindName(AslPldPanelList, +                    Node->Asl.Child->Asl.Value.String, +                    &Node->Asl.Child->Asl.Value.Integer)) +                { +                    AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); +                    break; +                } +            } + +            PldInfo.Panel = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_VERTICALPOSITION: + +            if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) +            { +                if (Node->Asl.Child->Asl.Value.Integer > 2) +                { +                    AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                    break; +                } +            } +            else /* PARSEOP_STRING */ +            { +                if (!OpcFindName(AslPldVerticalPositionList, +                    Node->Asl.Child->Asl.Value.String, +                    &Node->Asl.Child->Asl.Value.Integer)) +                { +                    AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); +                    break; +                } +            } + +            PldInfo.VerticalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_HORIZONTALPOSITION: + +            if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) +            { +                if (Node->Asl.Child->Asl.Value.Integer > 2) +                { +                    AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                    break; +                } +            } +            else /* PARSEOP_STRING */ +            { +                if (!OpcFindName(AslPldHorizontalPositionList, +                    Node->Asl.Child->Asl.Value.String, +                    &Node->Asl.Child->Asl.Value.Integer)) +                { +                    AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); +                    break; +                } +            } + +            PldInfo.HorizontalPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_SHAPE: + +            if (Node->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) +            { +                if (Node->Asl.Child->Asl.Value.Integer > 8) +                { +                    AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                    break; +                } +            } +            else /* PARSEOP_STRING */ +            { +                if (!OpcFindName(AslPldShapeList, +                    Node->Asl.Child->Asl.Value.String, +                    &Node->Asl.Child->Asl.Value.Integer)) +                { +                    AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Node, NULL); +                    break; +                } +            } + +            PldInfo.Shape = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_GROUPORIENTATION: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 1) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            PldInfo.GroupOrientation = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_GROUPTOKEN: +        case PARSEOP_PLD_GROUPPOSITION: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 255) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_GROUPTOKEN) +            { +                PldInfo.GroupToken = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else /* PARSEOP_PLD_GROUPPOSITION */ +            { +                PldInfo.GroupPosition = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } + +            break; + +        case PARSEOP_PLD_BAY: +        case PARSEOP_PLD_EJECTABLE: +        case PARSEOP_PLD_EJECTREQUIRED: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 1) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_BAY) +            { +                PldInfo.Bay = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else if (Node->Asl.ParseOpcode == PARSEOP_PLD_EJECTABLE) +            { +                PldInfo.Ejectable = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else /* PARSEOP_PLD_EJECTREQUIRED */ +            { +                PldInfo.OspmEjectRequired = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } + +            break; + +        case PARSEOP_PLD_CABINETNUMBER: +        case PARSEOP_PLD_CARDCAGENUMBER: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 255) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_CABINETNUMBER) +            { +                PldInfo.CabinetNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } +            else /* PARSEOP_PLD_CARDCAGENUMBER */ +            { +                PldInfo.CardCageNumber = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            } + +            break; + +        case PARSEOP_PLD_REFERENCE: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 1) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            PldInfo.Reference = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_ROTATION: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 7) +            { +                switch (Node->Asl.Child->Asl.Value.Integer) +                { +                case 45: + +                    Node->Asl.Child->Asl.Value.Integer = 1; +                    break; + +                case 90: + +                    Node->Asl.Child->Asl.Value.Integer = 2; +                    break; + +                case 135: + +                    Node->Asl.Child->Asl.Value.Integer = 3; +                    break; + +                case 180: + +                    Node->Asl.Child->Asl.Value.Integer = 4; +                    break; + +                case 225: + +                    Node->Asl.Child->Asl.Value.Integer = 5; +                    break; + +                case 270: + +                    Node->Asl.Child->Asl.Value.Integer = 6; +                    break; + +                case 315: + +                    Node->Asl.Child->Asl.Value.Integer = 7; +                    break; + +                default: + +                    AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                    break; +                } +            } + +            PldInfo.Rotation = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_ORDER: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 31) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            PldInfo.Order = (UINT8) Node->Asl.Child->Asl.Value.Integer; +            break; + +        case PARSEOP_PLD_VERTICALOFFSET: +        case PARSEOP_PLD_HORIZONTALOFFSET: + +            if (Node->Asl.Child->Asl.ParseOpcode != PARSEOP_INTEGER) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +                break; +            } + +            if (Node->Asl.Child->Asl.Value.Integer > 65535) +            { +                AslError(ASL_ERROR, ASL_MSG_RANGE, Node, NULL); +                break; +            } + +            if (Node->Asl.ParseOpcode == PARSEOP_PLD_VERTICALOFFSET) +            { +                PldInfo.VerticalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; +            } +            else /* PARSEOP_PLD_HORIZONTALOFFSET */ +            { +                PldInfo.HorizontalOffset = (UINT16) Node->Asl.Child->Asl.Value.Integer; +            } + +            break; + +        default: + +            AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, Node, NULL); +            break; +        } + +        Node = Node->Asl.Next; +    } + +    Buffer = OpcEncodePldBuffer(&PldInfo); + +    /* Change Op to a Buffer */ + +    Op->Asl.ParseOpcode = PARSEOP_BUFFER; +    Op->Common.AmlOpcode = AML_BUFFER_OP; + +    /* Disable further optimization */ + +    Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; +    UtSetParseOpName (Op); + +    /* Child node is the buffer length */ + +    NewOp = TrAllocateNode (PARSEOP_INTEGER); + +    NewOp->Asl.AmlOpcode     = AML_BYTE_OP; +    NewOp->Asl.Value.Integer = 20; +    NewOp->Asl.Parent        = Op; + +    Op->Asl.Child = NewOp; +    Op = NewOp; + +    /* Peer to the child is the raw buffer data */ + +    NewOp = TrAllocateNode (PARSEOP_RAW_DATA); +    NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER; +    NewOp->Asl.AmlLength     = 20; +    NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer); +    NewOp->Asl.Parent        = Op->Asl.Parent; + +    Op->Asl.Next = NewOp; +} + + +/******************************************************************************* + *   * FUNCTION:    OpcDoUuId   * - * PARAMETERS:  Op        - Parse node + * PARAMETERS:  Op                  - Parse node   *   * RETURN:      None   * @@ -673,7 +1415,7 @@ OpcDoUuId (      ACPI_PARSE_OBJECT       *NewOp; -    InString = (char *) Op->Asl.Value.String; +    InString = ACPI_CAST_PTR (char, Op->Asl.Value.String);      Buffer = UtLocalCalloc (16);      Status = AuValidateUuid (InString); @@ -712,7 +1454,7 @@ OpcDoUuId (      NewOp = TrAllocateNode (PARSEOP_RAW_DATA);      NewOp->Asl.AmlOpcode     = AML_RAW_DATA_BUFFER;      NewOp->Asl.AmlLength     = 16; -    NewOp->Asl.Value.String  = (char *) Buffer; +    NewOp->Asl.Value.String  = ACPI_CAST_PTR (char, Buffer);      NewOp->Asl.Parent        = Op->Asl.Parent;      Op->Asl.Next = NewOp; @@ -723,7 +1465,7 @@ OpcDoUuId (   *   * FUNCTION:    OpcGenerateAmlOpcode   * - * PARAMETERS:  Op        - Parse node + * PARAMETERS:  Op                  - Parse node   *   * RETURN:      None   * @@ -737,7 +1479,6 @@ void  OpcGenerateAmlOpcode (      ACPI_PARSE_OBJECT       *Op)  { -      UINT16                  Index; @@ -783,6 +1524,21 @@ OpcGenerateAmlOpcode (          OpcDoEisaId (Op);          break; +    case PARSEOP_PRINTF: + +        OpcDoPrintf (Op); +        break; + +    case PARSEOP_FPRINTF: + +        OpcDoFprintf (Op); +        break; + +    case PARSEOP_TOPLD: + +        OpcDoPld (Op); +        break; +      case PARSEOP_TOUUID:          OpcDoUuId (Op); diff --git a/source/compiler/asloptions.c b/source/compiler/asloptions.c index 63abcf4667a44..f5a1d865e47a8 100644 --- a/source/compiler/asloptions.c +++ b/source/compiler/asloptions.c @@ -184,7 +184,7 @@ AslDoOptions (          }          break; -    case 'b':   /* Debug output options */ +    case 'b':   /* Debug options */          switch (AcpiGbl_Optarg[0])          { @@ -193,10 +193,37 @@ AslDoOptions (              AslCompilerdebug = 1; /* same as yydebug */              DtParserdebug = 1;              PrParserdebug = 1; +            Gbl_DebugFlag = TRUE; +            break; + +        case 'p':   /* Prune ASL parse tree */ + +            /* Get the required argument */ + +            if (AcpiGetoptArgument (argc, argv)) +            { +                return (-1); +            } + +            Gbl_PruneParseTree = TRUE; +            Gbl_PruneDepth = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0); +            break; + +        case 's': + +            Gbl_DebugFlag = TRUE;              break;          case 't': +            /* Get the required argument */ + +            if (AcpiGetoptArgument (argc, argv)) +            { +                return (-1); +            } + +            Gbl_PruneType = (UINT8) strtoul (AcpiGbl_Optarg, NULL, 0);              break;          default: @@ -205,9 +232,6 @@ AslDoOptions (              return (-1);          } -        /* Produce debug output file */ - -        Gbl_DebugFlag = TRUE;          break;      case 'c': @@ -250,6 +274,12 @@ AslDoOptions (              break; +        case 'l':   /* Use legacy ASL code (not ASL+) for disassembly */ + +            Gbl_DoCompile = FALSE; +            AcpiGbl_CstyleDisassembly = FALSE; +            break; +          default:              printf ("Unknown option: -d%s\n", AcpiGbl_Optarg); @@ -530,7 +560,6 @@ AslDoOptions (          Gbl_OutputFilenamePrefix = AcpiGbl_Optarg;          UtConvertBackslashes (Gbl_OutputFilenamePrefix); -          Gbl_UseDefaultAmlFilename = FALSE;          break; diff --git a/source/compiler/aslparser.y b/source/compiler/aslparser.y index 5d21ce66a3c0a..827d4388c268c 100644 --- a/source/compiler/aslparser.y +++ b/source/compiler/aslparser.y @@ -99,7 +99,7 @@ AslLocalAllocate (   * These shift/reduce conflicts are expected. There should be zero   * reduce/reduce conflicts.   */ -%expect 86 +%expect 89  /*! [Begin] no source code translation */ diff --git a/source/compiler/aslprintf.c b/source/compiler/aslprintf.c new file mode 100644 index 0000000000000..d85abe2792c39 --- /dev/null +++ b/source/compiler/aslprintf.c @@ -0,0 +1,380 @@ +/****************************************************************************** + * + * Module Name: aslprintf - ASL Printf/Fprintf macro support + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "aslcompiler.y.h" +#include "amlcode.h" + +#define _COMPONENT          ACPI_COMPILER +        ACPI_MODULE_NAME    ("aslprintf") + + +/* Local prototypes */ + +static void +OpcCreateConcatenateNode ( +    ACPI_PARSE_OBJECT       *Op, +    ACPI_PARSE_OBJECT       *Node); + +static void +OpcParsePrintf ( +    ACPI_PARSE_OBJECT       *Op, +    ACPI_PARSE_OBJECT       *DestOp); + + +/******************************************************************************* + * + * FUNCTION:    OpcDoPrintf + * + * PARAMETERS:  Op                  - printf parse node + * + * RETURN:      None + * + * DESCRIPTION: Convert printf macro to a Store(..., Debug) AML operation. + * + ******************************************************************************/ + +void +OpcDoPrintf ( +    ACPI_PARSE_OBJECT       *Op) +{ +    ACPI_PARSE_OBJECT       *DestOp; + + +    /* Store destination is the Debug op */ + +    DestOp = TrAllocateNode (PARSEOP_DEBUG); +    DestOp->Asl.AmlOpcode = AML_DEBUG_OP; +    DestOp->Asl.Parent = Op; +    DestOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; + +    OpcParsePrintf (Op, DestOp); +} + + +/******************************************************************************* + * + * FUNCTION:    OpcDoFprintf + * + * PARAMETERS:  Op                  - fprintf parse node + * + * RETURN:      None + * + * DESCRIPTION: Convert fprintf macro to a Store AML operation. + * + ******************************************************************************/ + +void +OpcDoFprintf ( +    ACPI_PARSE_OBJECT       *Op) +{ +    ACPI_PARSE_OBJECT       *DestOp; + + +    /* Store destination is the first argument of fprintf */ + +    DestOp = Op->Asl.Child; +    Op->Asl.Child = DestOp->Asl.Next; +    DestOp->Asl.Next = NULL; + +    OpcParsePrintf (Op, DestOp); +} + + +/******************************************************************************* + * + * FUNCTION:    OpcParsePrintf + * + * PARAMETERS:  Op                  - Printf parse node + *              DestOp              - Destination of Store operation + * + * RETURN:      None + * + * DESCRIPTION: Convert printf macro to a Store AML operation. The printf + *              macro parse tree is layed out as follows: + * + *              Op        - printf parse op + *              Op->Child - Format string + *              Op->Next  - Format string arguments + * + ******************************************************************************/ + +static void +OpcParsePrintf ( +    ACPI_PARSE_OBJECT       *Op, +    ACPI_PARSE_OBJECT       *DestOp) +{ +    char                    *Format; +    char                    *StartPosition = NULL; +    ACPI_PARSE_OBJECT       *ArgNode; +    ACPI_PARSE_OBJECT       *NextNode; +    UINT32                  StringLength = 0; +    char                    *NewString; +    BOOLEAN                 StringToProcess = FALSE; +    ACPI_PARSE_OBJECT       *NewOp; + + +    /* Get format string */ + +    Format = ACPI_CAST_PTR (char, Op->Asl.Child->Asl.Value.String); +    ArgNode = Op->Asl.Child->Asl.Next; + +    /* +     * Detach argument list so that we can use a NULL check to distinguish +     * the first concatenation operation we need to make +     */ +    Op->Asl.Child = NULL; + +    for (; *Format; ++Format) +    { +        if (*Format != '%') +        { +            if (!StringToProcess) +            { +                /* Mark the beginning of a string */ + +                StartPosition = Format; +                StringToProcess = TRUE; +            } + +            ++StringLength; +            continue; +        } + +        /* Save string, if any, to new string object and concat it */ + +        if (StringToProcess) +        { +            NewString = UtStringCacheCalloc (StringLength + 1); +            ACPI_STRNCPY (NewString, StartPosition, StringLength); + +            NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL); +            NewOp->Asl.Value.String = NewString; +            NewOp->Asl.AmlOpcode = AML_STRING_OP; +            NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING; +            NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; + +            OpcCreateConcatenateNode(Op, NewOp); + +            StringLength = 0; +            StringToProcess = FALSE; +        } + +        ++Format; + +        /* +         * We have a format parameter and will need an argument to go +         * with it +         */ +        if (!ArgNode || +            ArgNode->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) +        { +            AslError(ASL_ERROR, ASL_MSG_ARG_COUNT_LO, Op, NULL); +            return; +        } + +        /* +         * We do not support sub-specifiers of printf (flags, width, +         * precision, length). For specifiers we only support %x/%X for +         * hex or %s for strings. Also, %o for generic "acpi object". +         */ +        switch (*Format) +        { +        case 's': + +            if (ArgNode->Asl.ParseOpcode != PARSEOP_STRING_LITERAL) +            { +                AslError(ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgNode, +                    "String required"); +                return; +            } + +            NextNode = ArgNode->Asl.Next; +            ArgNode->Asl.Next = NULL; +            OpcCreateConcatenateNode(Op, ArgNode); +            ArgNode = NextNode; +            continue; + +        case 'X': +        case 'x': +        case 'o': + +            NextNode = ArgNode->Asl.Next; +            ArgNode->Asl.Next = NULL; + +            /* +             * Append an empty string if the first argument is +             * not a string. This will implicitly conver the 2nd +             * concat source to a string per the ACPI specification. +             */ +            if (!Op->Asl.Child) +            { +                NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL); +                NewOp->Asl.Value.String = ""; +                NewOp->Asl.AmlOpcode = AML_STRING_OP; +                NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING; +                NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; + +                OpcCreateConcatenateNode(Op, NewOp); +            } + +            OpcCreateConcatenateNode(Op, ArgNode); +            ArgNode = NextNode; +            break; + +        default: + +            AslError(ASL_ERROR, ASL_MSG_INVALID_OPERAND, Op, +                "Unrecognized format specifier"); +            continue; +        } +    } + +    /* Process any remaining string */ + +    if (StringToProcess) +    { +        NewString = UtStringCacheCalloc (StringLength + 1); +        ACPI_STRNCPY (NewString, StartPosition, StringLength); + +        NewOp = TrAllocateNode (PARSEOP_STRING_LITERAL); +        NewOp->Asl.Value.String = NewString; +        NewOp->Asl.AcpiBtype = ACPI_BTYPE_STRING; +        NewOp->Asl.AmlOpcode = AML_STRING_OP; +        NewOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; + +        OpcCreateConcatenateNode(Op, NewOp); +    } + +    /* +     * If we get here and there's no child node then Format +     * was an empty string. Just make a no op. +     */ +    if (!Op->Asl.Child) +    { +        Op->Asl.ParseOpcode = PARSEOP_NOOP; +        AslError(ASL_WARNING, ASL_MSG_NULL_STRING, Op, +            "Converted to NOOP"); +        return; +    } + +     /* Check for erroneous extra arguments */ + +    if (ArgNode && +        ArgNode->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) +    { +        AslError(ASL_WARNING, ASL_MSG_ARG_COUNT_HI, ArgNode, +            "Extra arguments ignored"); +    } + +    /* Change Op to a Store */ + +    Op->Asl.ParseOpcode = PARSEOP_STORE; +    Op->Common.AmlOpcode = AML_STORE_OP; +    Op->Asl.CompileFlags  = 0; + +    /* Disable further optimization */ + +    Op->Asl.CompileFlags &= ~NODE_COMPILE_TIME_CONST; +    UtSetParseOpName (Op); + +    /* Set Store destination */ + +    Op->Asl.Child->Asl.Next = DestOp; +} + + +/******************************************************************************* + * + * FUNCTION:    OpcCreateConcatenateNode + * + * PARAMETERS:  Op                  - Parse node + *              Node                - Parse node to be concatenated + * + * RETURN:      None + * + * DESCRIPTION: Make Node the child of Op. If child node already exists, then + *              concat child with Node and makes concat node the child of Op. + * + ******************************************************************************/ + +static void +OpcCreateConcatenateNode ( +    ACPI_PARSE_OBJECT       *Op, +    ACPI_PARSE_OBJECT       *Node) +{ +    ACPI_PARSE_OBJECT       *NewConcatOp; + + +    if (!Op->Asl.Child) +    { +        Op->Asl.Child = Node; +        Node->Asl.Parent = Op; +        return; +    } + +    NewConcatOp = TrAllocateNode (PARSEOP_CONCATENATE); +    NewConcatOp->Asl.AmlOpcode = AML_CONCAT_OP; +    NewConcatOp->Asl.AcpiBtype = 0x7; +    NewConcatOp->Asl.LogicalLineNumber = Op->Asl.LogicalLineNumber; + +    /* First arg is child of Op*/ + +    NewConcatOp->Asl.Child = Op->Asl.Child; +    Op->Asl.Child->Asl.Parent = NewConcatOp; + +    /* Second arg is Node */ + +    NewConcatOp->Asl.Child->Asl.Next = Node; +    Node->Asl.Parent = NewConcatOp; + +    /* Third arg is Zero (not used) */ + +    NewConcatOp->Asl.Child->Asl.Next->Asl.Next = +        TrAllocateNode (PARSEOP_ZERO); +    NewConcatOp->Asl.Child->Asl.Next->Asl.Next->Asl.Parent = +        NewConcatOp; + +    Op->Asl.Child = NewConcatOp; +    NewConcatOp->Asl.Parent = Op; +} diff --git a/source/compiler/aslprune.c b/source/compiler/aslprune.c new file mode 100644 index 0000000000000..b80ee159624e0 --- /dev/null +++ b/source/compiler/aslprune.c @@ -0,0 +1,239 @@ +/****************************************************************************** + * + * Module Name: aslprune - Parse tree prune utility + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions, and the following disclaimer, + *    without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + *    substantially similar to the "NO WARRANTY" disclaimer below + *    ("Disclaimer") and any redistribution must be conditioned upon + *    including a substantially similar Disclaimer requirement for further + *    binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + *    of any contributors may be used to endorse or promote products derived + *    from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include "aslcompiler.h" +#include "aslcompiler.y.h" +#include "acapps.h" + +#define _COMPONENT          ACPI_COMPILER +        ACPI_MODULE_NAME    ("aslprune") + + +/* Local prototypes */ + +static ACPI_STATUS +PrTreePruneWalk ( +    ACPI_PARSE_OBJECT       *Op, +    UINT32                  Level, +    void                    *Context); + +static void +PrPrintObjectAtLevel ( +    UINT32                  Level, +    const char              *ObjectName); + + +typedef struct acpi_prune_info +{ +    UINT32                  PruneLevel; +    UINT16                  ParseOpcode; +    UINT16                  Count; + +} ACPI_PRUNE_INFO; + + +/******************************************************************************* + * + * FUNCTION:    AslPruneParseTree + * + * PARAMETERS:  PruneDepth              - Number of levels to prune + *              Type                    - Prune type (Device, Method, etc.) + * + * RETURN:      None + * + * DESCRIPTION: Prune off one or more levels of the ASL parse tree + * + ******************************************************************************/ + +void +AslPruneParseTree ( +    UINT32                  PruneDepth, +    UINT32                  Type) +{ +    ACPI_PRUNE_INFO         PruneObj; + + +    PruneObj.PruneLevel = PruneDepth; +    PruneObj.Count = 0; + +    switch (Type) +    { +    case 0: +        PruneObj.ParseOpcode = (UINT16) PARSEOP_DEVICE; +        break; + +    case 1: +        PruneObj.ParseOpcode = (UINT16) PARSEOP_METHOD; +        break; + +    case 2: +        PruneObj.ParseOpcode = (UINT16) PARSEOP_IF; +        break; + +    default: +        AcpiOsPrintf ("Unsupported type: %u\n", Type); +        return; +    } + +    AcpiOsPrintf ("Pruning parse tree, from depth %u\n", +        PruneDepth); + +    AcpiOsPrintf ("\nRemoving Objects:\n"); + +    TrWalkParseTree (RootNode, ASL_WALK_VISIT_DOWNWARD, +        PrTreePruneWalk, NULL, ACPI_CAST_PTR (void, &PruneObj)); + +    AcpiOsPrintf ("\n%u Total Objects Removed\n", PruneObj.Count); +} + + +/******************************************************************************* + * + * FUNCTION:    PrPrintObjectAtLevel + * + * PARAMETERS:  Level                   - Current nesting level + *              ObjectName              - ACPI name for the object + * + * RETURN:      None + * + * DESCRIPTION: Print object name with indent + * + ******************************************************************************/ + +static void +PrPrintObjectAtLevel ( +    UINT32                  Level, +    const char              *ObjectName) +{ +    UINT32                  i; + + +    for (i = 0; i < Level; i++) +    { +        AcpiOsPrintf ("  "); +    } + +    AcpiOsPrintf ("[%s] at Level [%u]\n", ObjectName, Level); +} + + +/******************************************************************************* + * + * FUNCTION:    PrTreePruneWalk + * + * PARAMETERS:  Parse tree walk callback + * + * RETURN:      Status + * + * DESCRIPTION: Prune off one or more levels of the ASL parse tree + * + * Current objects that can be pruned are: Devices, Methods, and If/Else + * blocks. + * + ******************************************************************************/ + +static ACPI_STATUS +PrTreePruneWalk ( +    ACPI_PARSE_OBJECT       *Op, +    UINT32                  Level, +    void                    *Context) +{ +    ACPI_PRUNE_INFO         *PruneObj = (ACPI_PRUNE_INFO *) Context; + + +    /* We only care about objects below the Prune Level threshold */ + +    if (Level <= PruneObj->PruneLevel) +    { +        return (AE_OK); +    } + +    if ((Op->Asl.ParseOpcode != PruneObj->ParseOpcode) && +       !(Op->Asl.ParseOpcode == PARSEOP_ELSE && +             PruneObj->ParseOpcode == PARSEOP_IF)) +    { +        return (AE_OK); +    } + +    switch (Op->Asl.ParseOpcode) +    { +    case PARSEOP_METHOD: + +        AcpiOsPrintf ("Method"); +        PrPrintObjectAtLevel (Level, Op->Asl.Child->Asl.Value.Name); +        Op->Asl.Child->Asl.Next->Asl.Next->Asl.Next->Asl.Next->Asl.Next->Asl.Next = NULL; +        PruneObj->Count++; +        break; + +    case PARSEOP_DEVICE: + +        AcpiOsPrintf ("Device"); +        PrPrintObjectAtLevel (Level, Op->Asl.Child->Asl.Value.Name); +        Op->Asl.Child->Asl.Next = NULL; +        PruneObj->Count++; +        break; + +    case PARSEOP_IF: +    case PARSEOP_ELSE: + +        if (Op->Asl.ParseOpcode == PARSEOP_ELSE) +        { +            PrPrintObjectAtLevel(Level, "Else"); +            Op->Asl.Child = NULL; +        } +        else +        { +            PrPrintObjectAtLevel(Level, "If"); +            Op->Asl.Child->Asl.Next = NULL; +        } + +        PruneObj->Count++; +        break; + +    default: + +        break; +    } + +    return (AE_OK); +} diff --git a/source/compiler/aslrules.y b/source/compiler/aslrules.y index 2bc48db11f6ae..7c47eb3e307a5 100644 --- a/source/compiler/aslrules.y +++ b/source/compiler/aslrules.y @@ -92,6 +92,149 @@ DefinitionBlockTerm              '{' TermList '}'        {$$ = TrLinkChildren ($<n>3,7,$4,$6,$8,$10,$12,$14,$18);}      ; +    /* +     * ASL Extensions: C-style math/logical operators and expressions. +     * The implementation transforms these operators into the standard +     * AML opcodes and syntax. +     * +     * Supported operators and precedence rules (high-to-low) +     * +     * NOTE: The operator precedence and associativity rules are +     * implemented by the tokens in asltokens.y +     * +     * (left-to-right): +     *  1)      ( ) expr++ expr-- +     * +     * (right-to-left): +     *  2)      ! ~ +     * +     * (left-to-right): +     *  3)      *   /   % +     *  4)      +   - +     *  5)      >>  << +     *  6)      <   >   <=  >= +     *  7)      ==  != +     *  8)      & +     *  9)      ^ +     *  10)     | +     *  11)     && +     *  12)     || +     * +     * (right-to-left): +     *  13)     = += -= *= /= %= <<= >>= &= ^= |= +     */ +Expression + +    /* Unary operators */ + +    : PARSEOP_EXP_LOGICAL_NOT           {$<n>$ = TrCreateLeafNode (PARSEOP_LNOT);} +        TermArg                         {$$ = TrLinkChildren ($<n>2,1,$3);} +    | PARSEOP_EXP_NOT                   {$<n>$ = TrCreateLeafNode (PARSEOP_NOT);} +        TermArg                         {$$ = TrLinkChildren ($<n>2,2,$3,TrCreateLeafNode (PARSEOP_ZERO));} + +    | SuperName PARSEOP_EXP_INCREMENT   {$<n>$ = TrCreateLeafNode (PARSEOP_INCREMENT);} +                                        {$$ = TrLinkChildren ($<n>3,1,$1);} +    | SuperName PARSEOP_EXP_DECREMENT   {$<n>$ = TrCreateLeafNode (PARSEOP_DECREMENT);} +                                        {$$ = TrLinkChildren ($<n>3,1,$1);} + +    /* Binary operators: math and logical */ + +    | TermArg PARSEOP_EXP_ADD           {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_DIVIDE        {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,4,$1,$4,TrCreateLeafNode (PARSEOP_ZERO), +                                            TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_MODULO        {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_MULTIPLY      {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_SHIFT_LEFT    {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_SHIFT_RIGHT   {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_SUBTRACT      {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} + +    | TermArg PARSEOP_EXP_AND           {$<n>$ = TrCreateLeafNode (PARSEOP_AND);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_OR            {$<n>$ = TrCreateLeafNode (PARSEOP_OR);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} +    | TermArg PARSEOP_EXP_XOR           {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4,TrCreateLeafNode (PARSEOP_ZERO));} + +    | TermArg PARSEOP_EXP_GREATER       {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATER);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} +    | TermArg PARSEOP_EXP_GREATER_EQUAL {$<n>$ = TrCreateLeafNode (PARSEOP_LGREATEREQUAL);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} +    | TermArg PARSEOP_EXP_LESS          {$<n>$ = TrCreateLeafNode (PARSEOP_LLESS);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} +    | TermArg PARSEOP_EXP_LESS_EQUAL    {$<n>$ = TrCreateLeafNode (PARSEOP_LLESSEQUAL);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} + +    | TermArg PARSEOP_EXP_EQUAL         {$<n>$ = TrCreateLeafNode (PARSEOP_LEQUAL);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} +    | TermArg PARSEOP_EXP_NOT_EQUAL     {$<n>$ = TrCreateLeafNode (PARSEOP_LNOTEQUAL);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} + +    | TermArg PARSEOP_EXP_LOGICAL_AND   {$<n>$ = TrCreateLeafNode (PARSEOP_LAND);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} +    | TermArg PARSEOP_EXP_LOGICAL_OR    {$<n>$ = TrCreateLeafNode (PARSEOP_LOR);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,2,$1,$4);} + +      /* Parentheses */ + +    | '(' TermArg ')'                   { $$ = $2;} +    ; + +EqualsTerm + +    /* All assignment-type operations */ + +    : SuperName PARSEOP_EXP_EQUALS +        TermArg                         {$$ = TrCreateAssignmentNode ($1, $3);} + +    | TermArg PARSEOP_EXP_ADD_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_ADD);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_DIV_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_DIVIDE);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,4,$1,$4,TrCreateLeafNode (PARSEOP_ZERO), +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_MOD_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_MOD);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_MUL_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_MULTIPLY);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_SHL_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTLEFT);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_SHR_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_SHIFTRIGHT);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_SUB_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_SUBTRACT);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_AND_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_AND);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_OR_EQ         {$<n>$ = TrCreateLeafNode (PARSEOP_OR);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} + +    | TermArg PARSEOP_EXP_XOR_EQ        {$<n>$ = TrCreateLeafNode (PARSEOP_XOR);} +        TermArg                         {$$ = TrLinkChildren ($<n>3,3,$1,$4, +                                            TrSetNodeFlags (TrCreateTargetOperand ($1, NULL), NODE_IS_TARGET));} +    ; + +  /* ACPI 3.0 -- allow semicolons between terms */  TermList @@ -104,6 +247,7 @@ TermList  Term      : Object                        {} +    | Expression                    {}      | Type1Opcode                   {}      | Type2Opcode                   {}      | Type2IntegerOpcode            {} @@ -211,7 +355,8 @@ Removed from TermArg due to reduce/reduce conflicts  */  TermArg -    : Type2Opcode                   {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);} +    : Expression                    {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);} +    | Type2Opcode                   {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}      | DataObject                    {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}      | NameString                    {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);}      | ArgTerm                       {$$ = TrSetNodeFlags ($1, NODE_IS_TERM_ARG);} @@ -305,6 +450,7 @@ Type2Opcode      | RefOfTerm                     {}      | SizeOfTerm                    {}      | StoreTerm                     {} +    | EqualsTerm                    {}      | TimerTerm                     {}      | WaitTerm                      {}      | UserTerm                      {} @@ -362,6 +508,8 @@ Type2BufferOpcode                   /* "Type5" Opcodes */  Type2BufferOrStringOpcode      : ConcatTerm                    {} +    | PrintfTerm                    {} +    | FprintfTerm                   {}      | MidTerm                       {}      ; @@ -387,6 +535,7 @@ Type4Opcode  Type5Opcode      : ResourceTemplateTerm          {}      | UnicodeTerm                   {} +    | ToPLDTerm                     {}      | ToUUIDTerm                    {}      ; @@ -1370,6 +1519,86 @@ ToIntegerTerm          error ')'                   {$$ = AslDoError(); yyclearin;}      ; +PldKeyword +    : PARSEOP_PLD_REVISION          {$$ = TrCreateLeafNode (PARSEOP_PLD_REVISION);} +    | PARSEOP_PLD_IGNORECOLOR       {$$ = TrCreateLeafNode (PARSEOP_PLD_IGNORECOLOR);} +    | PARSEOP_PLD_RED               {$$ = TrCreateLeafNode (PARSEOP_PLD_RED);} +    | PARSEOP_PLD_GREEN             {$$ = TrCreateLeafNode (PARSEOP_PLD_GREEN);} +    | PARSEOP_PLD_BLUE              {$$ = TrCreateLeafNode (PARSEOP_PLD_BLUE);} +    | PARSEOP_PLD_WIDTH             {$$ = TrCreateLeafNode (PARSEOP_PLD_WIDTH);} +    | PARSEOP_PLD_HEIGHT            {$$ = TrCreateLeafNode (PARSEOP_PLD_HEIGHT);} +    | PARSEOP_PLD_USERVISIBLE       {$$ = TrCreateLeafNode (PARSEOP_PLD_USERVISIBLE);} +    | PARSEOP_PLD_DOCK              {$$ = TrCreateLeafNode (PARSEOP_PLD_DOCK);} +    | PARSEOP_PLD_LID               {$$ = TrCreateLeafNode (PARSEOP_PLD_LID);} +    | PARSEOP_PLD_PANEL             {$$ = TrCreateLeafNode (PARSEOP_PLD_PANEL);} +    | PARSEOP_PLD_VERTICALPOSITION  {$$ = TrCreateLeafNode (PARSEOP_PLD_VERTICALPOSITION);} +    | PARSEOP_PLD_HORIZONTALPOSITION {$$ = TrCreateLeafNode (PARSEOP_PLD_HORIZONTALPOSITION);} +    | PARSEOP_PLD_SHAPE             {$$ = TrCreateLeafNode (PARSEOP_PLD_SHAPE);} +    | PARSEOP_PLD_GROUPORIENTATION  {$$ = TrCreateLeafNode (PARSEOP_PLD_GROUPORIENTATION);} +    | PARSEOP_PLD_GROUPTOKEN        {$$ = TrCreateLeafNode (PARSEOP_PLD_GROUPTOKEN);} +    | PARSEOP_PLD_GROUPPOSITION     {$$ = TrCreateLeafNode (PARSEOP_PLD_GROUPPOSITION);} +    | PARSEOP_PLD_BAY               {$$ = TrCreateLeafNode (PARSEOP_PLD_BAY);} +    | PARSEOP_PLD_EJECTABLE         {$$ = TrCreateLeafNode (PARSEOP_PLD_EJECTABLE);} +    | PARSEOP_PLD_EJECTREQUIRED     {$$ = TrCreateLeafNode (PARSEOP_PLD_EJECTREQUIRED);} +    | PARSEOP_PLD_CABINETNUMBER     {$$ = TrCreateLeafNode (PARSEOP_PLD_CABINETNUMBER);} +    | PARSEOP_PLD_CARDCAGENUMBER    {$$ = TrCreateLeafNode (PARSEOP_PLD_CARDCAGENUMBER);} +    | PARSEOP_PLD_REFERENCE         {$$ = TrCreateLeafNode (PARSEOP_PLD_REFERENCE);} +    | PARSEOP_PLD_ROTATION          {$$ = TrCreateLeafNode (PARSEOP_PLD_ROTATION);} +    | PARSEOP_PLD_ORDER             {$$ = TrCreateLeafNode (PARSEOP_PLD_ORDER);} +    | PARSEOP_PLD_RESERVED          {$$ = TrCreateLeafNode (PARSEOP_PLD_RESERVED);} +    | PARSEOP_PLD_VERTICALOFFSET    {$$ = TrCreateLeafNode (PARSEOP_PLD_VERTICALOFFSET);} +    | PARSEOP_PLD_HORIZONTALOFFSET  {$$ = TrCreateLeafNode (PARSEOP_PLD_HORIZONTALOFFSET);} +    ; + +PldKeywordList +    :                               {$$ = NULL;} +    | PldKeyword +        PARSEOP_EXP_EQUALS Integer  {$$ = TrLinkChildren ($1,1,$3);} +    | PldKeyword +        PARSEOP_EXP_EQUALS String   {$$ = TrLinkChildren ($1,1,$3);} +    | PldKeywordList ','            /* Allows a trailing comma at list end */ +    | PldKeywordList ',' +        PldKeyword +        PARSEOP_EXP_EQUALS Integer  {$$ = TrLinkPeerNode ($1,TrLinkChildren ($3,1,$5));} +    | PldKeywordList ',' +        PldKeyword +        PARSEOP_EXP_EQUALS String   {$$ = TrLinkPeerNode ($1,TrLinkChildren ($3,1,$5));} +    ; + +ToPLDTerm +    : PARSEOP_TOPLD '('             {$<n>$ = TrCreateLeafNode (PARSEOP_TOPLD);} +        PldKeywordList +        ')'                         {$$ = TrLinkChildren ($<n>3,1,$4);} +    | PARSEOP_TOPLD '(' +        error ')'                   {$$ = AslDoError(); yyclearin;} +    ; + +PrintfArgList +    :                               {$$ = NULL;} +    | TermArg                       {$$ = $1;} +    | PrintfArgList ',' +       TermArg                      {$$ = TrLinkPeerNode ($1, $3);} +    ; + +PrintfTerm +    : PARSEOP_PRINTF '('            {$<n>$ = TrCreateLeafNode (PARSEOP_PRINTF);} +        StringData +        PrintfArgList +        ')'                         {$$ = TrLinkChildren ($<n>3,2,$4,$5);} +    | PARSEOP_PRINTF '(' +        error ')'                   {$$ = AslDoError(); yyclearin;} +    ; + +FprintfTerm +    : PARSEOP_FPRINTF '('            {$<n>$ = TrCreateLeafNode (PARSEOP_FPRINTF);} +        TermArg ',' +        StringData +        PrintfArgList +        ')'                         {$$ = TrLinkChildren ($<n>3,3,$4,$6,$7);} +    | PARSEOP_FPRINTF '(' +        error ')'                   {$$ = AslDoError(); yyclearin;} +    ; +  ToStringTerm      : PARSEOP_TOSTRING '('          {$<n>$ = TrCreateLeafNode (PARSEOP_TOSTRING);}          TermArg diff --git a/source/compiler/asltokens.y b/source/compiler/asltokens.y index c296fea30bec6..0473f5d22ab09 100644 --- a/source/compiler/asltokens.y +++ b/source/compiler/asltokens.y @@ -376,6 +376,88 @@ NoEcho('  %token <i> PARSEOP_XOR  %token <i> PARSEOP_ZERO +/* ToPld macro */ + +%token <i> PARSEOP_TOPLD +%token <i> PARSEOP_PLD_REVISION +%token <i> PARSEOP_PLD_IGNORECOLOR +%token <i> PARSEOP_PLD_RED +%token <i> PARSEOP_PLD_GREEN +%token <i> PARSEOP_PLD_BLUE +%token <i> PARSEOP_PLD_WIDTH +%token <i> PARSEOP_PLD_HEIGHT +%token <i> PARSEOP_PLD_USERVISIBLE +%token <i> PARSEOP_PLD_DOCK +%token <i> PARSEOP_PLD_LID +%token <i> PARSEOP_PLD_PANEL +%token <i> PARSEOP_PLD_VERTICALPOSITION +%token <i> PARSEOP_PLD_HORIZONTALPOSITION +%token <i> PARSEOP_PLD_SHAPE +%token <i> PARSEOP_PLD_GROUPORIENTATION +%token <i> PARSEOP_PLD_GROUPTOKEN +%token <i> PARSEOP_PLD_GROUPPOSITION +%token <i> PARSEOP_PLD_BAY +%token <i> PARSEOP_PLD_EJECTABLE +%token <i> PARSEOP_PLD_EJECTREQUIRED +%token <i> PARSEOP_PLD_CABINETNUMBER +%token <i> PARSEOP_PLD_CARDCAGENUMBER +%token <i> PARSEOP_PLD_REFERENCE +%token <i> PARSEOP_PLD_ROTATION +%token <i> PARSEOP_PLD_ORDER +%token <i> PARSEOP_PLD_RESERVED +%token <i> PARSEOP_PLD_VERTICALOFFSET +%token <i> PARSEOP_PLD_HORIZONTALOFFSET + +/* + * C-style expression parser. These must appear after all of the + * standard ASL operators and keywords. + * + * Note: The order of these tokens implements the precedence rules + * (low precedence to high). See aslrules.y for an exhaustive list. + */ +%right <i> PARSEOP_EXP_EQUALS +           PARSEOP_EXP_ADD_EQ +           PARSEOP_EXP_SUB_EQ +           PARSEOP_EXP_MUL_EQ +           PARSEOP_EXP_DIV_EQ +           PARSEOP_EXP_MOD_EQ +           PARSEOP_EXP_SHL_EQ +           PARSEOP_EXP_SHR_EQ +           PARSEOP_EXP_AND_EQ +           PARSEOP_EXP_XOR_EQ +           PARSEOP_EXP_OR_EQ + +%left <i>  PARSEOP_EXP_LOGICAL_OR +%left <i>  PARSEOP_EXP_LOGICAL_AND +%left <i>  PARSEOP_EXP_OR +%left <i>  PARSEOP_EXP_XOR +%left <i>  PARSEOP_EXP_AND +%left <i>  PARSEOP_EXP_EQUAL +           PARSEOP_EXP_NOT_EQUAL +%left <i>  PARSEOP_EXP_GREATER +           PARSEOP_EXP_LESS +           PARSEOP_EXP_GREATER_EQUAL +           PARSEOP_EXP_LESS_EQUAL +%left <i>  PARSEOP_EXP_SHIFT_RIGHT +           PARSEOP_EXP_SHIFT_LEFT +%left <i>  PARSEOP_EXP_ADD +           PARSEOP_EXP_SUBTRACT +%left <i>  PARSEOP_EXP_MULTIPLY +           PARSEOP_EXP_DIVIDE +           PARSEOP_EXP_MODULO + +%right <i> PARSEOP_EXP_NOT +           PARSEOP_EXP_LOGICAL_NOT + +%left <i>  PARSEOP_EXP_INCREMENT +           PARSEOP_EXP_DECREMENT + +%token <i> PARSEOP_PRINTF +%token <i> PARSEOP_FPRINTF +/* Specific parentheses tokens are not used at this time */ +           /* PARSEOP_EXP_PAREN_OPEN */ +           /* PARSEOP_EXP_PAREN_CLOSE */ +  /*   * Special functions. These should probably stay at the end of this   * table. diff --git a/source/compiler/asltree.c b/source/compiler/asltree.c index 38644e8412521..4219ffe7c8a2b 100644 --- a/source/compiler/asltree.c +++ b/source/compiler/asltree.c @@ -448,6 +448,124 @@ TrSetEndLineNumber (  /*******************************************************************************   * + * FUNCTION:    TrCreateAssignmentNode + * + * PARAMETERS:  Target              - Assignment target + *              Source              - Assignment source + * + * RETURN:      Pointer to the new node. Aborts on allocation failure + * + * DESCRIPTION: Implements the C-style '=' operator. It changes the parse + *              tree if possible to utilize the last argument of the math + *              operators which is a target operand -- thus saving invocation + *              of and additional Store() operator. An optimization. + * + ******************************************************************************/ + +ACPI_PARSE_OBJECT * +TrCreateAssignmentNode ( +    ACPI_PARSE_OBJECT       *Target, +    ACPI_PARSE_OBJECT       *Source) +{ +    ACPI_PARSE_OBJECT       *TargetOp; +    ACPI_PARSE_OBJECT       *SourceOp1; +    ACPI_PARSE_OBJECT       *SourceOp2; +    ACPI_PARSE_OBJECT       *Operator; + + +    DbgPrint (ASL_PARSE_OUTPUT, +        "\nTrCreateAssignmentNode  Line [%u to %u] Source %s Target %s\n", +        Source->Asl.LineNumber, Source->Asl.EndLine, +        UtGetOpName (Source->Asl.ParseOpcode), +        UtGetOpName (Target->Asl.ParseOpcode)); + +    TrSetNodeFlags (Target, NODE_IS_TARGET); + +    switch (Source->Asl.ParseOpcode) +    { +    /* +     * Only these operators can be optimized because they have +     * a target operand +     */ +    case PARSEOP_ADD: +    case PARSEOP_AND: +    case PARSEOP_DIVIDE: +    case PARSEOP_MOD: +    case PARSEOP_MULTIPLY: +    case PARSEOP_NOT: +    case PARSEOP_OR: +    case PARSEOP_SHIFTLEFT: +    case PARSEOP_SHIFTRIGHT: +    case PARSEOP_SUBTRACT: +    case PARSEOP_XOR: + +        break; + +    /* Otherwise, just create a normal Store operator */ + +    default: + +        goto CannotOptimize; +    } + +    /* +     * Transform the parse tree such that the target is moved to the +     * last operand of the operator +     */ +    SourceOp1 = Source->Asl.Child; +    SourceOp2 = SourceOp1->Asl.Next; + +    /* NOT only has one operand, but has a target */ + +    if (Source->Asl.ParseOpcode == PARSEOP_NOT) +    { +        SourceOp2 = SourceOp1; +    } + +    /* DIVIDE has an extra target operand (remainder) */ + +    if (Source->Asl.ParseOpcode == PARSEOP_DIVIDE) +    { +        SourceOp2 = SourceOp2->Asl.Next; +    } + +    TargetOp = SourceOp2->Asl.Next; + +    /* +     * Can't perform this optimization if there already is a target +     * for the operator (ZERO is a "no target" placeholder). +     */ +    if (TargetOp->Asl.ParseOpcode != PARSEOP_ZERO) +    { +        goto CannotOptimize; +    } + +    /* Link in the target as the final operand */ + +    SourceOp2->Asl.Next = Target; +    Target->Asl.Parent = Source; + +    return (Source); + + +CannotOptimize: + +    Operator = TrAllocateNode (PARSEOP_STORE); +    TrLinkChildren (Operator, 2, Source, Target); + +    /* Set the appropriate line numbers for the new node */ + +    Operator->Asl.LineNumber        = Target->Asl.LineNumber; +    Operator->Asl.LogicalLineNumber = Target->Asl.LogicalLineNumber; +    Operator->Asl.LogicalByteOffset = Target->Asl.LogicalByteOffset; +    Operator->Asl.Column            = Target->Asl.Column; + +    return (Operator); +} + + +/******************************************************************************* + *   * FUNCTION:    TrCreateLeafNode   *   * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node @@ -563,6 +681,81 @@ TrCreateConstantLeafNode (  /*******************************************************************************   * + * FUNCTION:    TrCreateTargetOperand + * + * PARAMETERS:  OriginalOp          - Op to be copied + * + * RETURN:      Pointer to the new node. Aborts on allocation failure + * + * DESCRIPTION: Copy an existing node (and subtree). Used in ASL+ (C-style) + *              expressions where the target is the same as one of the + *              operands. A new node and subtree must be created from the + *              original so that the parse tree can be linked properly. + * + * NOTE:        This code is specific to target operands that are the last + *              operand in an ASL/AML operator. Meaning that the top-level + *              parse Op in a possible subtree has a NULL Next pointer. + *              This simplifies the recursion. + * + *              Subtree example: + *                  DeRefOf (Local1) += 32 + * + *              This gets converted to: + *                  Add (DeRefOf (Local1), 32, DeRefOf (Local1)) + * + *              Each DeRefOf has a single child, Local1. Even more complex + *              subtrees can be created via the Index and DeRefOf operators. + * + ******************************************************************************/ + +ACPI_PARSE_OBJECT * +TrCreateTargetOperand ( +    ACPI_PARSE_OBJECT       *OriginalOp, +    ACPI_PARSE_OBJECT       *ParentOp) +{ +    ACPI_PARSE_OBJECT       *Op; + + +    if (!OriginalOp) +    { +        return (NULL); +    } + +    Op = TrGetNextNode (); + +    /* Copy the pertinent values (omit link pointer fields) */ + +    Op->Asl.Value               = OriginalOp->Asl.Value; +    Op->Asl.Filename            = OriginalOp->Asl.Filename; +    Op->Asl.LineNumber          = OriginalOp->Asl.LineNumber; +    Op->Asl.LogicalLineNumber   = OriginalOp->Asl.LogicalLineNumber; +    Op->Asl.LogicalByteOffset   = OriginalOp->Asl.LogicalByteOffset; +    Op->Asl.Column              = OriginalOp->Asl.Column; +    Op->Asl.Flags               = OriginalOp->Asl.Flags; +    Op->Asl.CompileFlags        = OriginalOp->Asl.CompileFlags; +    Op->Asl.AmlOpcode           = OriginalOp->Asl.AmlOpcode; +    Op->Asl.ParseOpcode         = OriginalOp->Asl.ParseOpcode; +    Op->Asl.Parent              = ParentOp; +    UtSetParseOpName (Op); + +    /* Copy a possible subtree below this node */ + +    if (OriginalOp->Asl.Child) +    { +        Op->Asl.Child = TrCreateTargetOperand (OriginalOp->Asl.Child, Op); +    } + +    if (OriginalOp->Asl.Next) /* Null for top-level node */ +    { +        Op->Asl.Next = TrCreateTargetOperand (OriginalOp->Asl.Next, ParentOp); +    } + +    return (Op); +} + + +/******************************************************************************* + *   * FUNCTION:    TrCreateValuedLeafNode   *   * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node diff --git a/source/compiler/asltypes.y b/source/compiler/asltypes.y index b9914531b4e3b..ece54132e1d2c 100644 --- a/source/compiler/asltypes.y +++ b/source/compiler/asltypes.y @@ -285,8 +285,14 @@ NoEcho('  %type <n> ResourceMacroList  %type <n> ResourceMacroTerm  %type <n> ResourceTemplateTerm +%type <n> PldKeyword +%type <n> PldKeywordList +%type <n> ToPLDTerm  %type <n> ToUUIDTerm  %type <n> UnicodeTerm +%type <n> PrintfArgList +%type <n> PrintfTerm +%type <n> FprintfTerm  /* Resource Descriptors */ @@ -379,3 +385,9 @@ NoEcho('  %type <n> OptionalWordConst  %type <n> OptionalWordConstExpr  %type <n> OptionalXferSize + +/* + * C-style expression parser + */ +%type <n> Expression +%type <n> EqualsTerm diff --git a/source/compiler/aslwalks.c b/source/compiler/aslwalks.c index da4e9e31e9e0e..bbf64070c4d3e 100644 --- a/source/compiler/aslwalks.c +++ b/source/compiler/aslwalks.c @@ -294,6 +294,13 @@ AnOperandTypecheckWalkEnd (          {              RequiredBtypes = AnMapArgTypeToBtype (ArgType); +            if (!ArgOp) +            { +                AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, +                    "Null ArgOp in argument loop"); +                AslAbort (); +            } +              ThisNodeBtype = AnGetBtype (ArgOp);              if (ThisNodeBtype == ACPI_UINT32_MAX)              { diff --git a/source/compiler/aslxref.c b/source/compiler/aslxref.c index f26cfdd084014..2f47921704747 100644 --- a/source/compiler/aslxref.c +++ b/source/compiler/aslxref.c @@ -832,6 +832,8 @@ XfNamespaceLocateBegin (          if ((Op->Asl.Parent) &&             ((Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_REFOF)      ||              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_DEREFOF)    || +            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_PACKAGE)    || +            (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)||              (Op->Asl.Parent->Asl.ParseOpcode == PARSEOP_OBJECTTYPE)))          {              return_ACPI_STATUS (AE_OK); diff --git a/source/compiler/dtcompile.c b/source/compiler/dtcompile.c index e7dfabff15146..3168d4c72e5cf 100644 --- a/source/compiler/dtcompile.c +++ b/source/compiler/dtcompile.c @@ -41,7 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTCOMPILE_C__  #define _DECLARE_DT_GLOBALS  #include "aslcompiler.h" diff --git a/source/compiler/dtexpress.c b/source/compiler/dtexpress.c index 1c06587586741..c431ed36fd196 100644 --- a/source/compiler/dtexpress.c +++ b/source/compiler/dtexpress.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTEXPRESS_C__ -  #include "aslcompiler.h"  #include "dtcompiler.h"  #include "dtparser.y.h" diff --git a/source/compiler/dtfield.c b/source/compiler/dtfield.c index 98c87798c5434..bcbdab47891d7 100644 --- a/source/compiler/dtfield.c +++ b/source/compiler/dtfield.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTFIELD_C__ -  #include "aslcompiler.h"  #include "dtcompiler.h" diff --git a/source/compiler/dtio.c b/source/compiler/dtio.c index f8e35fdd8a3bc..e90695ab37df6 100644 --- a/source/compiler/dtio.c +++ b/source/compiler/dtio.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTIO_C__ -  #include "aslcompiler.h"  #include "dtcompiler.h"  #include "acapps.h" diff --git a/source/compiler/dtsubtable.c b/source/compiler/dtsubtable.c index d4394e38c366d..c29d69d970a13 100644 --- a/source/compiler/dtsubtable.c +++ b/source/compiler/dtsubtable.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTSUBTABLE_C__ -  #include "aslcompiler.h"  #include "dtcompiler.h" diff --git a/source/compiler/dttable.c b/source/compiler/dttable.c index a0dee31e6896e..bbe43d27bbc03 100644 --- a/source/compiler/dttable.c +++ b/source/compiler/dttable.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTTABLE_C__ -  /* Compile all complex data tables */  #include "aslcompiler.h" diff --git a/source/compiler/dtutils.c b/source/compiler/dtutils.c index 6927c56697f4f..a41b6b61b2d0a 100644 --- a/source/compiler/dtutils.c +++ b/source/compiler/dtutils.c @@ -41,8 +41,6 @@   * POSSIBILITY OF SUCH DAMAGES.   */ -#define __DTUTILS_C__ -  #include "aslcompiler.h"  #include "dtcompiler.h"  #include "actables.h"  | 
