diff options
Diffstat (limited to 'gnu-efi/lib/ia32')
-rw-r--r-- | gnu-efi/lib/ia32/efi_stub.S | 1 | ||||
-rw-r--r-- | gnu-efi/lib/ia32/initplat.c | 27 | ||||
-rw-r--r-- | gnu-efi/lib/ia32/math.c | 199 | ||||
-rw-r--r-- | gnu-efi/lib/ia32/setjmp.S | 45 |
4 files changed, 272 insertions, 0 deletions
diff --git a/gnu-efi/lib/ia32/efi_stub.S b/gnu-efi/lib/ia32/efi_stub.S new file mode 100644 index 00000000..464eae58 --- /dev/null +++ b/gnu-efi/lib/ia32/efi_stub.S @@ -0,0 +1 @@ +/* This stub is a stub to make the build happy */ diff --git a/gnu-efi/lib/ia32/initplat.c b/gnu-efi/lib/ia32/initplat.c new file mode 100644 index 00000000..7c887a67 --- /dev/null +++ b/gnu-efi/lib/ia32/initplat.c @@ -0,0 +1,27 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + initplat.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle EFI_UNUSED, + IN EFI_SYSTEM_TABLE *SystemTable EFI_UNUSED + ) +{ +} + diff --git a/gnu-efi/lib/ia32/math.c b/gnu-efi/lib/ia32/math.c new file mode 100644 index 00000000..fce7a8d4 --- /dev/null +++ b/gnu-efi/lib/ia32/math.c @@ -0,0 +1,199 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + math.c + +Abstract: + + + + +Revision History + +--*/ + +#include "lib.h" + + +// +// Declare runtime functions +// + +#ifdef RUNTIME_CODE +#ifndef __GNUC__ +#pragma RUNTIME_CODE(LShiftU64) +#pragma RUNTIME_CODE(RShiftU64) +#pragma RUNTIME_CODE(MultU64x32) +#pragma RUNTIME_CODE(DivU64x32) +#endif +#endif + +// +// +// + +UINT64 +LShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +// Left shift 64bit by 32bit and get a 64bit result +{ +#ifdef __GNUC__ + return Operand << Count; +#else + UINT64 Result; + _asm { + mov eax, dword ptr Operand[0] + mov edx, dword ptr Operand[4] + mov ecx, Count + and ecx, 63 + + shld edx, eax, cl + shl eax, cl + + cmp ecx, 32 + jc short ls10 + + mov edx, eax + xor eax, eax + +ls10: + mov dword ptr Result[0], eax + mov dword ptr Result[4], edx + } + + return Result; +#endif +} + +UINT64 +RShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +// Right shift 64bit by 32bit and get a 64bit result +{ +#ifdef __GNUC__ + return Operand >> Count; +#else + UINT64 Result; + _asm { + mov eax, dword ptr Operand[0] + mov edx, dword ptr Operand[4] + mov ecx, Count + and ecx, 63 + + shrd eax, edx, cl + shr edx, cl + + cmp ecx, 32 + jc short rs10 + + mov eax, edx + xor edx, edx + +rs10: + mov dword ptr Result[0], eax + mov dword ptr Result[4], edx + } + + return Result; +#endif +} + + +UINT64 +MultU64x32 ( + IN UINT64 Multiplicand, + IN UINTN Multiplier + ) +// Multiple 64bit by 32bit and get a 64bit result +{ +#ifdef __GNUC__ + return Multiplicand * Multiplier; +#else + UINT64 Result; + _asm { + mov eax, dword ptr Multiplicand[0] + mul Multiplier + mov dword ptr Result[0], eax + mov dword ptr Result[4], edx + mov eax, dword ptr Multiplicand[4] + mul Multiplier + add dword ptr Result[4], eax + } + + return Result; +#endif +} + +UINT64 +DivU64x32 ( + IN UINT64 Dividend, + IN UINTN Divisor, + OUT UINTN *Remainder OPTIONAL + ) +// divide 64bit by 32bit and get a 64bit result +// N.B. only works for 31bit divisors!! +{ +#if 0 && defined(__GNUC__) && !defined(__MINGW32__) + if (Remainder) + *Remainder = Dividend % Divisor; + return Dividend / Divisor; +#else + UINT32 Rem; + UINT32 bit; + + ASSERT (Divisor != 0); + ASSERT ((Divisor >> 31) == 0); + + // + // For each bit in the dividend + // + + Rem = 0; + for (bit=0; bit < 64; bit++) { +#if defined(__GNUC__) || defined(__MINGW32__) + asm ( + "shll $1, %0\n\t" + "rcll $1, 4%0\n\t" + "rcll $1, %2\n\t" + "mov %2, %%eax\n\t" + "cmp %1, %%eax\n\t" + "cmc\n\t" + "sbb %%eax, %%eax\n\t" + "sub %%eax, %0\n\t" + "and %1, %%eax\n\t" + "sub %%eax, %2" + : /* no outputs */ + : "m"(Dividend), "m"(Divisor), "m"(Rem) + : "cc","memory","%eax" + ); +#else + _asm { + shl dword ptr Dividend[0], 1 ; shift rem:dividend left one + rcl dword ptr Dividend[4], 1 + rcl dword ptr Rem, 1 + + mov eax, Rem + cmp eax, Divisor ; Is Rem >= Divisor? + cmc ; No - do nothing + sbb eax, eax ; Else, + sub dword ptr Dividend[0], eax ; set low bit in dividen + and eax, Divisor ; and + sub Rem, eax ; subtract divisor + } +#endif + } + + if (Remainder) { + *Remainder = Rem; + } + + return Dividend; +#endif +} diff --git a/gnu-efi/lib/ia32/setjmp.S b/gnu-efi/lib/ia32/setjmp.S new file mode 100644 index 00000000..aa9c0846 --- /dev/null +++ b/gnu-efi/lib/ia32/setjmp.S @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved. + * This program and the accompanying materials are licensed and made +available + * under the terms and conditions of the BSD License which accompanies +this + * distribution. The full text of the license may be found at + * http://opensource.org/licenses/bsd-license.php. + * + * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" +BASIS, + * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR + * IMPLIED. + */ + .text + .globl setjmp +#ifndef __MINGW32__ + .type setjmp, @function +#else + .def setjmp; .scl 2; .type 32; .endef +#endif +setjmp: + pop %ecx + movl (%esp), %edx + movl %ebx, (%edx) + movl %esi, 4(%edx) + movl %edi, 8(%edx) + movl %ebp, 12(%edx) + movl %esp, 16(%edx) + xorl %eax, %eax + jmp *%ecx + + .globl longjmp +#ifndef __MINGW32__ + .type longjmp, @function +#else + .def longjmp; .scl 2; .type 32; .endef +#endif +longjmp: + pop %eax + pop %edx + pop %eax + movl (%edx), %ebx + movl 4(%edx), %esi + movl 8(%edx), %edi |