aboutsummaryrefslogtreecommitdiff
path: root/compiler/dtexpress.c
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/dtexpress.c')
-rw-r--r--compiler/dtexpress.c284
1 files changed, 151 insertions, 133 deletions
diff --git a/compiler/dtexpress.c b/compiler/dtexpress.c
index 20a2e3eb1d06..cb7620eeb37a 100644
--- a/compiler/dtexpress.c
+++ b/compiler/dtexpress.c
@@ -45,6 +45,7 @@
#include "aslcompiler.h"
#include "dtcompiler.h"
+#include "dtparser.y.h"
#define _COMPONENT DT_COMPILER
ACPI_MODULE_NAME ("dtexpress")
@@ -52,11 +53,6 @@
/* Local prototypes */
-static UINT64
-DtResolveInteger (
- DT_FIELD *Field,
- char *IntegerString);
-
static void
DtInsertLabelField (
DT_FIELD *Field);
@@ -65,204 +61,226 @@ static DT_FIELD *
DtLookupLabel (
char *Name);
+/* Global used for errors during parse and related functions */
+
+DT_FIELD *Gbl_CurrentField;
+
/******************************************************************************
*
* FUNCTION: DtResolveIntegerExpression
*
* PARAMETERS: Field - Field object with Integer expression
+ * ReturnValue - Where the integer is returned
*
- * RETURN: A 64-bit integer value
+ * RETURN: Status, and the resolved 64-bit integer value
*
* DESCRIPTION: Resolve an integer expression to a single value. Supports
- * both integer constants and labels. Supported operators are:
- * +,-,*,/,%,|,&,^
+ * both integer constants and labels.
*
*****************************************************************************/
-UINT64
+ACPI_STATUS
DtResolveIntegerExpression (
- DT_FIELD *Field)
+ DT_FIELD *Field,
+ UINT64 *ReturnValue)
{
- char *IntegerString;
- char *Operator;
- UINT64 Value;
- UINT64 Value2;
+ UINT64 Result;
DbgPrint (ASL_DEBUG_OUTPUT, "Full Integer expression: %s\n",
Field->Value);
- strcpy (MsgBuffer, Field->Value); /* Must take a copy for strtok() */
+ Gbl_CurrentField = Field;
- /* Obtain and resolve the first operand */
+ Result = DtEvaluateExpression (Field->Value);
+ *ReturnValue = Result;
+ return (AE_OK);
+}
- IntegerString = strtok (MsgBuffer, " ");
- if (!IntegerString)
- {
- DtError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, Field, Field->Value);
- return (0);
- }
- Value = DtResolveInteger (Field, IntegerString);
- DbgPrint (ASL_DEBUG_OUTPUT, "Integer resolved to V1: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (Value));
+/******************************************************************************
+ *
+ * FUNCTION: DtDoOperator
+ *
+ * PARAMETERS: LeftValue - First 64-bit operand
+ * Operator - Parse token for the operator (EXPOP_*)
+ * RightValue - Second 64-bit operand
+ *
+ * RETURN: 64-bit result of the requested operation
+ *
+ * DESCRIPTION: Perform the various 64-bit integer math functions
+ *
+ *****************************************************************************/
- /*
- * Consume the entire expression string. For the rest of the
- * expression string, values are of the form:
- * <operator> <integer>
- */
- while (1)
+UINT64
+DtDoOperator (
+ UINT64 LeftValue,
+ UINT32 Operator,
+ UINT64 RightValue)
+{
+ UINT64 Result;
+
+
+ /* Perform the requested operation */
+
+ switch (Operator)
{
- Operator = strtok (NULL, " ");
- if (!Operator)
- {
- /* Normal exit */
+ case EXPOP_ONES_COMPLIMENT:
+ Result = ~RightValue;
+ break;
- DbgPrint (ASL_DEBUG_OUTPUT, "Expression Resolved to: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (Value));
+ case EXPOP_LOGICAL_NOT:
+ Result = !RightValue;
+ break;
- return (Value);
- }
+ case EXPOP_MULTIPLY:
+ Result = LeftValue * RightValue;
+ break;
- IntegerString = strtok (NULL, " ");
- if (!IntegerString ||
- (strlen (Operator) > 1))
+ case EXPOP_DIVIDE:
+ if (!RightValue)
{
- /* No corresponding operand for operator or invalid operator */
+ DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO,
+ Gbl_CurrentField, Gbl_CurrentField->Value);
+ return (0);
+ }
+ Result = LeftValue / RightValue;
+ break;
- DtError (ASL_ERROR, ASL_MSG_INVALID_EXPRESSION, Field, Field->Value);
+ case EXPOP_MODULO:
+ if (!RightValue)
+ {
+ DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO,
+ Gbl_CurrentField, Gbl_CurrentField->Value);
return (0);
}
+ Result = LeftValue % RightValue;
+ break;
- Value2 = DtResolveInteger (Field, IntegerString);
- DbgPrint (ASL_DEBUG_OUTPUT, "Integer resolved to V2: %8.8X%8.8X\n",
- ACPI_FORMAT_UINT64 (Value2));
+ case EXPOP_ADD:
+ Result = LeftValue + RightValue;
+ break;
- /* Perform the requested operation */
+ case EXPOP_SUBTRACT:
+ Result = LeftValue - RightValue;
+ break;
- switch (*Operator)
- {
- case '-':
- Value -= Value2;
- break;
+ case EXPOP_SHIFT_RIGHT:
+ Result = LeftValue >> RightValue;
+ break;
- case '+':
- Value += Value2;
- break;
+ case EXPOP_SHIFT_LEFT:
+ Result = LeftValue << RightValue;
+ break;
- case '*':
- Value *= Value2;
- break;
+ case EXPOP_LESS:
+ Result = LeftValue < RightValue;
+ break;
- case '|':
- Value |= Value2;
- break;
+ case EXPOP_GREATER:
+ Result = LeftValue > RightValue;
+ break;
- case '&':
- Value &= Value2;
- break;
+ case EXPOP_LESS_EQUAL:
+ Result = LeftValue <= RightValue;
+ break;
- case '^':
- Value ^= Value2;
- break;
+ case EXPOP_GREATER_EQUAL:
+ Result = LeftValue >= RightValue;
+ break;
- case '/':
- if (!Value2)
- {
- DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, Field, Field->Value);
- return (0);
- }
- Value /= Value2;
- break;
+ case EXPOP_EQUAL:
+ Result = LeftValue = RightValue;
+ break;
- case '%':
- if (!Value2)
- {
- DtError (ASL_ERROR, ASL_MSG_DIVIDE_BY_ZERO, Field, Field->Value);
- return (0);
- }
- Value %= Value2;
- break;
+ case EXPOP_NOT_EQUAL:
+ Result = LeftValue != RightValue;
+ break;
- default:
+ case EXPOP_AND:
+ Result = LeftValue & RightValue;
+ break;
- /* Unknown operator */
+ case EXPOP_XOR:
+ Result = LeftValue ^ RightValue;
+ break;
- DtFatal (ASL_MSG_INVALID_EXPRESSION, Field, Field->Value);
- break;
- }
+ case EXPOP_OR:
+ Result = LeftValue | RightValue;
+ break;
+
+ case EXPOP_LOGICAL_AND:
+ Result = LeftValue && RightValue;
+ break;
+
+ case EXPOP_LOGICAL_OR:
+ Result = LeftValue || RightValue;
+ break;
+
+ default:
+
+ /* Unknown operator */
+
+ DtFatal (ASL_MSG_INVALID_EXPRESSION,
+ Gbl_CurrentField, Gbl_CurrentField->Value);
+ return (0);
}
- return (Value);
+ DbgPrint (ASL_DEBUG_OUTPUT,
+ "IntegerEval: %s (%8.8X%8.8X %s %8.8X%8.8X) = %8.8X%8.8X\n",
+ Gbl_CurrentField->Value,
+ ACPI_FORMAT_UINT64 (LeftValue),
+ DtGetOpName (Operator),
+ ACPI_FORMAT_UINT64 (RightValue),
+ ACPI_FORMAT_UINT64 (Result));
+
+ return (Result);
}
/******************************************************************************
*
- * FUNCTION: DtResolveInteger
- *
- * PARAMETERS: Field - Field object with string to be resolved
- * IntegerString - Integer to be resolved
+ * FUNCTION: DtResolveLabel
*
- * RETURN: A 64-bit integer value
+ * PARAMETERS: LabelString - Contains the label
*
- * DESCRIPTION: Resolve a single integer string to a value. Supports both
- * integer constants and labels.
+ * RETURN: Table offset associated with the label
*
- * NOTE: References to labels must begin with a dollar sign ($)
+ * DESCRIPTION: Lookup a lable and return its value.
*
*****************************************************************************/
-static UINT64
-DtResolveInteger (
- DT_FIELD *Field,
- char *IntegerString)
+UINT64
+DtResolveLabel (
+ char *LabelString)
{
DT_FIELD *LabelField;
- UINT64 Value = 0;
- char *Message = NULL;
- ACPI_STATUS Status;
- DbgPrint (ASL_DEBUG_OUTPUT, "Resolve Integer: %s\n", IntegerString);
+ DbgPrint (ASL_DEBUG_OUTPUT, "Resolve Label: %s\n", LabelString);
/* Resolve a label reference to an integer (table offset) */
- if (*IntegerString == '$')
+ if (*LabelString != '$')
{
- LabelField = DtLookupLabel (IntegerString);
- if (!LabelField)
- {
- DtError (ASL_ERROR, ASL_MSG_UNKNOWN_LABEL, Field, IntegerString);
- return (0);
- }
-
- /* All we need from the label is the offset in the table */
-
- Value = LabelField->TableOffset;
- return (Value);
+ return (0);
}
- /* Convert string to an actual integer */
-
- Status = DtStrtoul64 (IntegerString, &Value);
- if (ACPI_FAILURE (Status))
+ LabelField = DtLookupLabel (LabelString);
+ if (!LabelField)
{
- if (Status == AE_LIMIT)
- {
- Message = "Constant larger than 64 bits";
- }
- else if (Status == AE_BAD_CHARACTER)
- {
- Message = "Invalid character in constant";
- }
-
- DtError (ASL_ERROR, ASL_MSG_INVALID_HEX_INTEGER, Field, Message);
+ DtError (ASL_ERROR, ASL_MSG_UNKNOWN_LABEL,
+ Gbl_CurrentField, LabelString);
+ return (0);
}
- return (Value);
+ /* All we need from the label is the offset in the table */
+
+ DbgPrint (ASL_DEBUG_OUTPUT, "Resolved Label: 0x%8.8X\n",
+ LabelField->TableOffset);
+
+ return (LabelField->TableOffset);
}