From 4b367408659af08fd44839866ec301285284e6f4 Mon Sep 17 00:00:00 2001 From: Robert Moore Date: Thu, 29 Sep 2016 14:04:23 -0700 Subject: [PATCH] Disassembler: Fix for Divide() support, new support for test suite Fixes a problem with complex expressions where an illegal mix of legacy ASL and ASL+ could be emitted. Adds new support for ASLTS that disables some disassembler optimizations could be changed during a conversion to ASL+. These expressions are now emitted in legacy ASL instead of ASL+. --- source/compiler/asloptions.c | 7 ++ source/components/disassembler/dmcstyle.c | 91 +++++++++++++++++++++++ source/include/acglobal.h | 1 + source/include/aclocal.h | 19 ++--- 4 files changed, 109 insertions(+), 9 deletions(-) diff --git a/source/compiler/asloptions.c b/source/compiler/asloptions.c index 6be638fd4..170ac4afe 100644 --- a/source/compiler/asloptions.c +++ b/source/compiler/asloptions.c @@ -633,6 +633,13 @@ AslDoOptions ( Gbl_CompileTimesFlag = TRUE; break; + case 'd': + + /* Disable disassembler code optimizations */ + + AcpiGbl_DoDisassemblerOptimizations = FALSE; + break; + case 'e': /* iASL: Disable External opcode generation */ diff --git a/source/components/disassembler/dmcstyle.c b/source/components/disassembler/dmcstyle.c index 7ff388f30..dcfc04486 100644 --- a/source/components/disassembler/dmcstyle.c +++ b/source/components/disassembler/dmcstyle.c @@ -170,6 +170,9 @@ AcpiDmCheckForSymbolicOpcode ( ACPI_PARSE_OBJECT *Child1; ACPI_PARSE_OBJECT *Child2; ACPI_PARSE_OBJECT *Target; + ACPI_PARSE_OBJECT *GrandChild1; + ACPI_PARSE_OBJECT *GrandChild2; + ACPI_PARSE_OBJECT *GrandTarget = NULL; /* Exit immediately if ASL+ not enabled */ @@ -179,6 +182,14 @@ AcpiDmCheckForSymbolicOpcode ( return (FALSE); } + /* Check for a non-ASL+ statement, propagate the flag */ + + if (Op->Common.Parent->Common.DisasmFlags & ACPI_PARSEOP_LEGACY_ASL_ONLY) + { + Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (FALSE); + } + /* Get the first operand */ Child1 = AcpiPsGetArg (Op, 0); @@ -395,6 +406,7 @@ AcpiDmCheckForSymbolicOpcode ( if (AcpiDmIsValidTarget (Target)) { Child1->Common.OperatorSymbol = NULL; + Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; return (FALSE); } @@ -411,6 +423,13 @@ AcpiDmCheckForSymbolicOpcode ( if (!AcpiDmIsValidTarget (Target)) { + if (Op->Common.Parent->Common.AmlOpcode == AML_STORE_OP) + { + Op->Common.DisasmFlags = 0; + Child1->Common.OperatorSymbol = NULL; + return (FALSE); + } + /* Not a valid target (placeholder only, from parser) */ break; } @@ -550,6 +569,69 @@ AcpiDmCheckForSymbolicOpcode ( /* * Target is the 2nd operand. * We know the target is valid, it is not optional. + * + * The following block implements "Ignore conversion if a store + * is followed by a math/bit operator that has no target". Used + * only for the ASL test suite. + */ + if (!AcpiGbl_DoDisassemblerOptimizations) + { + switch (Child1->Common.AmlOpcode) + { + /* This operator has two operands and two targets */ + + case AML_DIVIDE_OP: + + GrandChild1 = Child1->Common.Value.Arg; + GrandChild2 = GrandChild1->Common.Next; + GrandTarget = GrandChild2->Common.Next; + + if (GrandTarget && !AcpiDmIsValidTarget (GrandTarget)) + { + Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (FALSE); + } + GrandTarget = GrandTarget->Common.Next; + break; + + case AML_ADD_OP: + case AML_SUBTRACT_OP: + case AML_MULTIPLY_OP: + case AML_MOD_OP: + case AML_SHIFT_LEFT_OP: + case AML_SHIFT_RIGHT_OP: + case AML_BIT_AND_OP: + case AML_BIT_OR_OP: + case AML_BIT_XOR_OP: + case AML_INDEX_OP: + + /* These operators have two operands and a target */ + + GrandChild1 = Child1->Common.Value.Arg; + GrandChild2 = GrandChild1->Common.Next; + GrandTarget = GrandChild2->Common.Next; + break; + + case AML_BIT_NOT_OP: + + /* This operator has one operand and a target */ + + GrandChild1 = Child1->Common.Value.Arg; + GrandTarget = GrandChild1->Common.Next; + break; + + default: + break; + } + + if (GrandTarget && !AcpiDmIsValidTarget (GrandTarget)) + { + Op->Common.DisasmFlags |= ACPI_PARSEOP_LEGACY_ASL_ONLY; + return (FALSE); + } + } + + /* * In the parse tree, simply swap the target with the * source so that the target is processed first. */ @@ -635,6 +717,7 @@ AcpiDmCloseOperator ( { BOOLEAN IsCStyleOp = FALSE; + /* Always emit paren if ASL+ disassembly disabled */ if (!AcpiGbl_CstyleDisassembly) @@ -643,6 +726,14 @@ AcpiDmCloseOperator ( return; } + /* Check for a non-ASL+ statement */ + + if (Op->Common.DisasmFlags & ACPI_PARSEOP_LEGACY_ASL_ONLY) + { + AcpiOsPrintf (")"); + return; + } + /* Check if we need to add an additional closing paren */ switch (Op->Common.AmlOpcode) diff --git a/source/include/acglobal.h b/source/include/acglobal.h index 20d3d0b28..d0e160f56 100644 --- a/source/include/acglobal.h +++ b/source/include/acglobal.h @@ -394,6 +394,7 @@ ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_CstyleDisassembly, TRUE); ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_ForceAmlDisassembly, FALSE); ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Verbose, TRUE); ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DmEmitExternalOpcodes, FALSE); +ACPI_INIT_GLOBAL (BOOLEAN, AcpiGbl_DoDisassemblerOptimizations, TRUE); ACPI_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Disasm); ACPI_GLOBAL (BOOLEAN, AcpiGbl_DmOpt_Listing); diff --git a/source/include/aclocal.h b/source/include/aclocal.h index c5dc19abc..4d28120da 100644 --- a/source/include/aclocal.h +++ b/source/include/aclocal.h @@ -989,7 +989,7 @@ typedef union acpi_parse_value ACPI_PARSE_VALUE Value; /* Value or args associated with the opcode */\ UINT8 ArgListLength; /* Number of elements in the arg list */\ ACPI_DISASM_ONLY_MEMBERS (\ - UINT8 DisasmFlags; /* Used during AML disassembly */\ + UINT16 DisasmFlags; /* Used during AML disassembly */\ UINT8 DisasmOpcode; /* Subtype used for disassembly */\ char *OperatorSymbol;/* Used for C-style operator name strings */\ char AmlOpName[16]) /* Op name (debug only) */ @@ -1109,14 +1109,15 @@ typedef struct acpi_parse_state /* Parse object DisasmFlags */ -#define ACPI_PARSEOP_IGNORE 0x01 -#define ACPI_PARSEOP_PARAMETER_LIST 0x02 -#define ACPI_PARSEOP_EMPTY_TERMLIST 0x04 -#define ACPI_PARSEOP_PREDEFINED_CHECKED 0x08 -#define ACPI_PARSEOP_CLOSING_PAREN 0x10 -#define ACPI_PARSEOP_COMPOUND_ASSIGNMENT 0x20 -#define ACPI_PARSEOP_ASSIGNMENT 0x40 -#define ACPI_PARSEOP_ELSEIF 0x80 +#define ACPI_PARSEOP_IGNORE 0x0001 +#define ACPI_PARSEOP_PARAMETER_LIST 0x0002 +#define ACPI_PARSEOP_EMPTY_TERMLIST 0x0004 +#define ACPI_PARSEOP_PREDEFINED_CHECKED 0x0008 +#define ACPI_PARSEOP_CLOSING_PAREN 0x0010 +#define ACPI_PARSEOP_COMPOUND_ASSIGNMENT 0x0020 +#define ACPI_PARSEOP_ASSIGNMENT 0x0040 +#define ACPI_PARSEOP_ELSEIF 0x0080 +#define ACPI_PARSEOP_LEGACY_ASL_ONLY 0x0100 /*****************************************************************************