Skip to content

Commit

Permalink
Disassembler: Fix support for non-commutative symbolic operators.
Browse files Browse the repository at this point in the history
Care must be taken when disassembling operators like subtract and
shift left. The operators cannot be interchanged, so there are
additional restrictions on when these operators can be converted
to a compound assignment. David Box.
  • Loading branch information
acpibob committed May 29, 2015
1 parent 6005294 commit 5bc9437
Showing 1 changed file with 61 additions and 14 deletions.
75 changes: 61 additions & 14 deletions source/components/disassembler/dmcstyle.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,23 +409,70 @@ AcpiDmCheckForSymbolicOpcode (
*/
AcpiDmPromoteTarget (Op, Target);

/*
* Check for possible conversion to a "Compound Assignment".
*
* Determine if either operand is the same as the target
* and display compound assignment operator and other operand.
*/
if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
(AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
/* Check operands for conversion to a "Compound Assignment" */

switch (Op->Common.AmlOpcode)
{
Target->Common.OperatorSymbol =
AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);
/* Commutative operators */

/* Convert operator to compound assignment */
case AML_ADD_OP:
case AML_MULTIPLY_OP:
case AML_BIT_AND_OP:
case AML_BIT_OR_OP:
case AML_BIT_XOR_OP:
/*
* For the commutative operators, we can convert to a
* compound statement only if at least one (either) operand
* is the same as the target.
*
* Add (A, B, A) --> A += B
* Add (B, A, A) --> A += B
* Add (B, C, A) --> A = (B + C)
*/
if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)) ||
(AcpiDmIsTargetAnOperand (Target, Child2, TRUE)))
{
Target->Common.OperatorSymbol =
AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);

Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
Child1->Common.OperatorSymbol = NULL;
return (TRUE);
/* Convert operator to compound assignment */

Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
Child1->Common.OperatorSymbol = NULL;
return (TRUE);
}
break;

/* Non-commutative operators */

case AML_SUBTRACT_OP:
case AML_DIVIDE_OP:
case AML_MOD_OP:
case AML_SHIFT_LEFT_OP:
case AML_SHIFT_RIGHT_OP:
/*
* For the non-commutative operators, we can convert to a
* compound statement only if the target is the same as the
* first operand.
*
* Subtract (A, B, A) --> A -= B
* Subtract (B, A, A) --> A = (B - A)
*/
if ((AcpiDmIsTargetAnOperand (Target, Child1, TRUE)))
{
Target->Common.OperatorSymbol =
AcpiDmGetCompoundSymbol (Op->Common.AmlOpcode);

/* Convert operator to compound assignment */

Op->Common.DisasmFlags |= ACPI_PARSEOP_COMPOUND;
Child1->Common.OperatorSymbol = NULL;
return (TRUE);
}
break;

default:
break;
}

/*
Expand Down

1 comment on commit 5bc9437

@RehabMan
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: This is fix for issue #75

Please sign in to comment.