+/*++\r
+\r
+Copyright (c) 2004 - 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+\r
+Module Name:\r
+\r
+ Match64.c\r
+ \r
+Abstract: \r
+\r
+ Leaf math worker functions that require 64-bit arithmetic support from the\r
+ compiler.\r
+\r
+--*/\r
+\r
+#include "BaseLibInternal.h"\r
+\r
+/**\r
+ Shifts a 64-bit integer left between 0 and 63 bits. The low bits\r
+ are filled with zeros. The shifted value is returned.\r
+\r
+ This function shifts the 64-bit value Operand to the left by Count bits. The\r
+ low Count bits are set to zero. The shifted value is returned.\r
+\r
+ @param Operand The 64-bit operand to shift left.\r
+ @param Count The number of bits to shift left.\r
+\r
+ @return Operand << Count\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathLShiftU64 (\r
+ IN UINT64 Operand,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ return Operand << Count;\r
+}\r
+\r
+/**\r
+ Shifts a 64-bit integer right between 0 and 63 bits. This high bits\r
+ are filled with zeros. The shifted value is returned.\r
+\r
+ This function shifts the 64-bit value Operand to the right by Count bits. The\r
+ high Count bits are set to zero. The shifted value is returned.\r
+\r
+ @param Operand The 64-bit operand to shift right.\r
+ @param Count The number of bits to shift right.\r
+\r
+ @return Operand >> Count\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathRShiftU64 (\r
+ IN UINT64 Operand,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ return Operand >> Count;\r
+}\r
+\r
+/**\r
+ Shifts a 64-bit integer right between 0 and 63 bits. The high bits\r
+ are filled with original integer's bit 63. The shifted value is returned.\r
+\r
+ This function shifts the 64-bit value Operand to the right by Count bits. The\r
+ high Count bits are set to bit 63 of Operand. The shifted value is returned.\r
+\r
+ If Count is greater than 63, then ASSERT().\r
+\r
+ @param Operand The 64-bit operand to shift right.\r
+ @param Count The number of bits to shift right.\r
+\r
+ @return Operand arithmetically shifted right by Count\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathARShiftU64 (\r
+ IN UINT64 Operand,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ INTN TestValue;\r
+\r
+ //\r
+ // Test if this compiler supports arithmetic shift\r
+ //\r
+ TestValue = (((-1) << (sizeof (-1) * 8 - 1)) >> (sizeof (-1) * 8 - 1));\r
+ if (TestValue == -1) {\r
+ //\r
+ // Arithmetic shift is supported\r
+ //\r
+ return (UINT64)((INT64)Operand >> Count);\r
+ }\r
+\r
+ //\r
+ // Arithmetic is not supported\r
+ //\r
+ return (Operand >> Count) |\r
+ ((INTN)Operand < 0 ? ~((UINTN)-1 >> Count) : 0);\r
+}\r
+\r
+\r
+/**\r
+ Rotates a 64-bit integer left between 0 and 63 bits, filling\r
+ the low bits with the high bits that were rotated.\r
+\r
+ This function rotates the 64-bit value Operand to the left by Count bits. The\r
+ low Count bits are fill with the high Count bits of Operand. The rotated\r
+ value is returned.\r
+\r
+ @param Operand The 64-bit operand to rotate left.\r
+ @param Count The number of bits to rotate left.\r
+\r
+ @return Operand <<< Count\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathLRotU64 (\r
+ IN UINT64 Operand,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ return (Operand << Count) | (Operand >> (64 - Count));\r
+}\r
+\r
+/**\r
+ Rotates a 64-bit integer right between 0 and 63 bits, filling\r
+ the high bits with the high low bits that were rotated.\r
+\r
+ This function rotates the 64-bit value Operand to the right by Count bits.\r
+ The high Count bits are fill with the low Count bits of Operand. The rotated\r
+ value is returned.\r
+\r
+ @param Operand The 64-bit operand to rotate right.\r
+ @param Count The number of bits to rotate right.\r
+\r
+ @return Operand >>> Count\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathRRotU64 (\r
+ IN UINT64 Operand,\r
+ IN UINTN Count\r
+ )\r
+{\r
+ return (Operand >> Count) | (Operand << (64 - Count));\r
+}\r
+\r
+/**\r
+ Switches the endianess of a 64-bit integer.\r
+\r
+ This function swaps the bytes in a 64-bit unsigned value to switch the value\r
+ from little endian to big endian or vice versa. The byte swapped value is\r
+ returned.\r
+\r
+ @param Operand A 64-bit unsigned value.\r
+\r
+ @return The byte swaped Operand.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathSwapBytes64 (\r
+ IN UINT64 Operand\r
+ )\r
+{\r
+ UINT64 LowerBytes;\r
+ UINT64 HigherBytes;\r
+\r
+ LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand);\r
+ HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));\r
+\r
+ return (LowerBytes << 32 | HigherBytes);\r
+}\r
+\r
+/**\r
+ Multiples a 64-bit unsigned integer by a 32-bit unsigned integer\r
+ and generates a 64-bit unsigned result.\r
+\r
+ This function multiples the 64-bit unsigned value Multiplicand by the 32-bit\r
+ unsigned value Multiplier and generates a 64-bit unsigned result. This 64-\r
+ bit unsigned result is returned.\r
+\r
+ @param Multiplicand A 64-bit unsigned value.\r
+ @param Multiplier A 32-bit unsigned value.\r
+\r
+ @return Multiplicand * Multiplier\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathMultU64x32 (\r
+ IN UINT64 Multiplicand,\r
+ IN UINT32 Multiplier\r
+ )\r
+{\r
+ return Multiplicand * Multiplier;\r
+}\r
+\r
+\r
+/**\r
+ Multiples a 64-bit unsigned integer by a 64-bit unsigned integer\r
+ and generates a 64-bit unsigned result.\r
+\r
+ This function multiples the 64-bit unsigned value Multiplicand by the 64-bit\r
+ unsigned value Multiplier and generates a 64-bit unsigned result. This 64-\r
+ bit unsigned result is returned.\r
+\r
+ @param Multiplicand A 64-bit unsigned value.\r
+ @param Multiplier A 64-bit unsigned value.\r
+\r
+ @return Multiplicand * Multiplier\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathMultU64x64 (\r
+ IN UINT64 Multiplicand,\r
+ IN UINT64 Multiplier\r
+ )\r
+{\r
+ return Multiplicand * Multiplier;\r
+}\r
+\r
+/**\r
+ Divides a 64-bit unsigned integer by a 32-bit unsigned integer and\r
+ generates a 64-bit unsigned result.\r
+\r
+ This function divides the 64-bit unsigned value Dividend by the 32-bit\r
+ unsigned value Divisor and generates a 64-bit unsigned quotient. This\r
+ function returns the 64-bit unsigned quotient.\r
+\r
+ @param Dividend A 64-bit unsigned value.\r
+ @param Divisor A 32-bit unsigned value.\r
+\r
+ @return Dividend / Divisor\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathDivU64x32 (\r
+ IN UINT64 Dividend,\r
+ IN UINT32 Divisor\r
+ )\r
+{\r
+ return Dividend / Divisor;\r
+}\r
+\r
+/**\r
+ Divides a 64-bit unsigned integer by a 32-bit unsigned integer\r
+ and generates a 32-bit unsigned remainder.\r
+\r
+ This function divides the 64-bit unsigned value Dividend by the 32-bit\r
+ unsigned value Divisor and generates a 32-bit remainder. This function\r
+ returns the 32-bit unsigned remainder.\r
+\r
+ @param Dividend A 64-bit unsigned value.\r
+ @param Divisor A 32-bit unsigned value.\r
+\r
+ @return Dividend % Divisor\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+InternalMathModU64x32 (\r
+ IN UINT64 Dividend,\r
+ IN UINT32 Divisor\r
+ )\r
+{\r
+ return (UINT32)(Dividend % Divisor);\r
+}\r
+\r
+/**\r
+ Divides a 64-bit unsigned integer by a 32-bit unsigned integer and\r
+ generates a 64-bit unsigned result and an optional 32-bit unsigned remainder.\r
+\r
+ This function divides the 64-bit unsigned value Dividend by the 32-bit\r
+ unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder\r
+ is not NULL, then the 32-bit unsigned remainder is returned in Remainder.\r
+ This function returns the 64-bit unsigned quotient.\r
+\r
+ @param Dividend A 64-bit unsigned value.\r
+ @param Divisor A 32-bit unsigned value.\r
+ @param Remainder A pointer to a 32-bit unsigned value. This parameter is\r
+ optional and may be NULL.\r
+\r
+ @return Dividend / Divisor\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathDivRemU64x32 (\r
+ IN UINT64 Dividend,\r
+ IN UINT32 Divisor,\r
+ OUT UINT32 *Remainder OPTIONAL\r
+ )\r
+{\r
+ if (Remainder != NULL) {\r
+ *Remainder = (UINT32)(Dividend % Divisor);\r
+ }\r
+ return Dividend / Divisor;\r
+}\r
+\r
+/**\r
+ Divides a 64-bit unsigned integer by a 64-bit unsigned integer and\r
+ generates a 64-bit unsigned result and an optional 64-bit unsigned remainder.\r
+\r
+ This function divides the 64-bit unsigned value Dividend by the 64-bit\r
+ unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder\r
+ is not NULL, then the 64-bit unsigned remainder is returned in Remainder.\r
+ This function returns the 64-bit unsigned quotient.\r
+\r
+ @param Dividend A 64-bit unsigned value.\r
+ @param Divisor A 64-bit unsigned value.\r
+ @param Remainder A pointer to a 64-bit unsigned value. This parameter is\r
+ optional and may be NULL.\r
+\r
+ @return Dividend / Divisor\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+InternalMathDivRemU64x64 (\r
+ IN UINT64 Dividend,\r
+ IN UINT64 Divisor,\r
+ OUT UINT64 *Remainder OPTIONAL\r
+ )\r
+{\r
+ if (Remainder != NULL) {\r
+ *Remainder = Dividend % Divisor;\r
+ }\r
+ return Dividend / Divisor;\r
+}\r
+\r
+/**\r
+ Divides a 64-bit signed integer by a 64-bit signed integer and\r
+ generates a 64-bit signed result and a optional 64-bit signed remainder.\r
+\r
+ This function divides the 64-bit unsigned value Dividend by the 64-bit\r
+ unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder\r
+ is not NULL, then the 64-bit unsigned remainder is returned in Remainder.\r
+ This function returns the 64-bit unsigned quotient.\r
+\r
+ @param Dividend A 64-bit signed value.\r
+ @param Divisor A 64-bit signed value.\r
+ @param Remainder A pointer to a 64-bit signed value. This parameter is\r
+ optional and may be NULL.\r
+\r
+ @return Dividend / Divisor\r
+\r
+**/\r
+INT64\r
+InternalMathDivRemS64x64 (\r
+ IN INT64 Dividend,\r
+ IN INT64 Divisor,\r
+ OUT INT64 *Remainder OPTIONAL\r
+ )\r
+{\r
+ if (Remainder != NULL) {\r
+ *Remainder = Dividend % Divisor;\r
+ }\r
+ return Dividend / Divisor;\r
+}\r