📄 exmisc.c
字号:
goto Cleanup; } NewBuf = ReturnDesc->String.Pointer; /* Concatenate the strings */ ACPI_STRCPY (NewBuf, Operand0->String.Pointer); ACPI_STRCPY (NewBuf + Operand0->String.Length, LocalOperand1->String.Pointer); break; case ACPI_TYPE_BUFFER: /* Result of two Buffers is a Buffer */ ReturnDesc = AcpiUtCreateBufferObject ((ACPI_SIZE) (Operand0->Buffer.Length + LocalOperand1->Buffer.Length)); if (!ReturnDesc) { Status = AE_NO_MEMORY; goto Cleanup; } NewBuf = (char *) ReturnDesc->Buffer.Pointer; /* Concatenate the buffers */ ACPI_MEMCPY (NewBuf, Operand0->Buffer.Pointer, Operand0->Buffer.Length); ACPI_MEMCPY (NewBuf + Operand0->Buffer.Length, LocalOperand1->Buffer.Pointer, LocalOperand1->Buffer.Length); break; default: /* Invalid object type, should not happen here */ ACPI_ERROR ((AE_INFO, "Invalid object type: %X", ACPI_GET_OBJECT_TYPE (Operand0))); Status =AE_AML_INTERNAL; goto Cleanup; } *ActualReturnDesc = ReturnDesc;Cleanup: if (LocalOperand1 != Operand1) { AcpiUtRemoveReference (LocalOperand1); } return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION: AcpiExDoMathOp * * PARAMETERS: Opcode - AML opcode * Integer0 - Integer operand #0 * Integer1 - Integer operand #1 * * RETURN: Integer result of the operation * * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the * math functions here is to prevent a lot of pointer dereferencing * to obtain the operands. * ******************************************************************************/ACPI_INTEGERAcpiExDoMathOp ( UINT16 Opcode, ACPI_INTEGER Integer0, ACPI_INTEGER Integer1){ ACPI_FUNCTION_ENTRY (); switch (Opcode) { case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */ return (Integer0 + Integer1); case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */ return (Integer0 & Integer1); case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */ return (~(Integer0 & Integer1)); case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */ return (Integer0 | Integer1); case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */ return (~(Integer0 | Integer1)); case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */ return (Integer0 ^ Integer1); case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */ return (Integer0 * Integer1); case AML_SHIFT_LEFT_OP: /* ShiftLeft (Operand, ShiftCount, Result)*/ /* * We need to check if the shiftcount is larger than the integer bit * width since the behavior of this is not well-defined in the C language. */ if (Integer1 >= AcpiGbl_IntegerBitWidth) { return (0); } return (Integer0 << Integer1); case AML_SHIFT_RIGHT_OP: /* ShiftRight (Operand, ShiftCount, Result) */ /* * We need to check if the shiftcount is larger than the integer bit * width since the behavior of this is not well-defined in the C language. */ if (Integer1 >= AcpiGbl_IntegerBitWidth) { return (0); } return (Integer0 >> Integer1); case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ return (Integer0 - Integer1); default: return (0); }}/******************************************************************************* * * FUNCTION: AcpiExDoLogicalNumericOp * * PARAMETERS: Opcode - AML opcode * Integer0 - Integer operand #0 * Integer1 - Integer operand #1 * LogicalResult - TRUE/FALSE result of the operation * * RETURN: Status * * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric * operators (LAnd and LOr), both operands must be integers. * * Note: cleanest machine code seems to be produced by the code * below, rather than using statements of the form: * Result = (Integer0 && Integer1); * ******************************************************************************/ACPI_STATUSAcpiExDoLogicalNumericOp ( UINT16 Opcode, ACPI_INTEGER Integer0, ACPI_INTEGER Integer1, BOOLEAN *LogicalResult){ ACPI_STATUS Status = AE_OK; BOOLEAN LocalResult = FALSE; ACPI_FUNCTION_TRACE (ExDoLogicalNumericOp); switch (Opcode) { case AML_LAND_OP: /* LAnd (Integer0, Integer1) */ if (Integer0 && Integer1) { LocalResult = TRUE; } break; case AML_LOR_OP: /* LOr (Integer0, Integer1) */ if (Integer0 || Integer1) { LocalResult = TRUE; } break; default: Status = AE_AML_INTERNAL; break; } /* Return the logical result and status */ *LogicalResult = LocalResult; return_ACPI_STATUS (Status);}/******************************************************************************* * * FUNCTION: AcpiExDoLogicalOp * * PARAMETERS: Opcode - AML opcode * Operand0 - operand #0 * Operand1 - operand #1 * LogicalResult - TRUE/FALSE result of the operation * * RETURN: Status * * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the * functions here is to prevent a lot of pointer dereferencing * to obtain the operands and to simplify the generation of the * logical value. For the Numeric operators (LAnd and LOr), both * operands must be integers. For the other logical operators, * operands can be any combination of Integer/String/Buffer. The * first operand determines the type to which the second operand * will be converted. * * Note: cleanest machine code seems to be produced by the code * below, rather than using statements of the form: * Result = (Operand0 == Operand1); * ******************************************************************************/ACPI_STATUSAcpiExDoLogicalOp ( UINT16 Opcode, ACPI_OPERAND_OBJECT *Operand0, ACPI_OPERAND_OBJECT *Operand1, BOOLEAN *LogicalResult){ ACPI_OPERAND_OBJECT *LocalOperand1 = Operand1; ACPI_INTEGER Integer0; ACPI_INTEGER Integer1; UINT32 Length0; UINT32 Length1; ACPI_STATUS Status = AE_OK; BOOLEAN LocalResult = FALSE; int Compare; ACPI_FUNCTION_TRACE (ExDoLogicalOp); /* * Convert the second operand if necessary. The first operand * determines the type of the second operand, (See the Data Types * section of the ACPI 3.0+ specification.) Both object types are * guaranteed to be either Integer/String/Buffer by the operand * resolution mechanism. */ switch (ACPI_GET_OBJECT_TYPE (Operand0)) { case ACPI_TYPE_INTEGER: Status = AcpiExConvertToInteger (Operand1, &LocalOperand1, 16); break; case ACPI_TYPE_STRING: Status = AcpiExConvertToString (Operand1, &LocalOperand1, ACPI_IMPLICIT_CONVERT_HEX); break; case ACPI_TYPE_BUFFER: Status = AcpiExConvertToBuffer (Operand1, &LocalOperand1); break; default: Status = AE_AML_INTERNAL; break; } if (ACPI_FAILURE (Status)) { goto Cleanup; } /* * Two cases: 1) Both Integers, 2) Both Strings or Buffers */ if (ACPI_GET_OBJECT_TYPE (Operand0) == ACPI_TYPE_INTEGER) { /* * 1) Both operands are of type integer * Note: LocalOperand1 may have changed above */ Integer0 = Operand0->Integer.Value; Integer1 = LocalOperand1->Integer.Value; switch (Opcode) { case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ if (Integer0 == Integer1) { LocalResult = TRUE; } break; case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ if (Integer0 > Integer1) { LocalResult = TRUE; } break; case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ if (Integer0 < Integer1) { LocalResult = TRUE; } break; default: Status = AE_AML_INTERNAL; break; } } else { /* * 2) Both operands are Strings or both are Buffers * Note: Code below takes advantage of common Buffer/String * object fields. LocalOperand1 may have changed above. Use * memcmp to handle nulls in buffers. */ Length0 = Operand0->Buffer.Length; Length1 = LocalOperand1->Buffer.Length; /* Lexicographic compare: compare the data bytes */ Compare = ACPI_MEMCMP (Operand0->Buffer.Pointer, LocalOperand1->Buffer.Pointer, (Length0 > Length1) ? Length1 : Length0); switch (Opcode) { case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ /* Length and all bytes must be equal */ if ((Length0 == Length1) && (Compare == 0)) { /* Length and all bytes match ==> TRUE */ LocalResult = TRUE; } break; case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ if (Compare > 0) { LocalResult = TRUE; goto Cleanup; /* TRUE */ } if (Compare < 0) { goto Cleanup; /* FALSE */ } /* Bytes match (to shortest length), compare lengths */ if (Length0 > Length1) { LocalResult = TRUE; } break; case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ if (Compare > 0) { goto Cleanup; /* FALSE */ } if (Compare < 0) { LocalResult = TRUE; goto Cleanup; /* TRUE */ } /* Bytes match (to shortest length), compare lengths */ if (Length0 < Length1) { LocalResult = TRUE; } break; default: Status = AE_AML_INTERNAL; break; } }Cleanup: /* New object was created if implicit conversion performed - delete */ if (LocalOperand1 != Operand1) { AcpiUtRemoveReference (LocalOperand1); } /* Return the logical result and status */ *LogicalResult = LocalResult; return_ACPI_STATUS (Status);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -