Home | History | Annotate | Download | only in Ia32
      1 #/*++
      2 #
      3 #Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
      4 #This program and the accompanying materials
      5 #are licensed and made available under the terms and conditions of the BSD License
      6 #which accompanies this distribution.  The full text of the license may be found at
      7 #http://opensource.org/licenses/bsd-license.php
      8 #
      9 #THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 #WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 #
     12 #Module Name:
     13 #
     14 #  LShiftU64.c
     15 #
     16 #Abstract:
     17 #
     18 #  64-bit left shift function for IA-32
     19 #
     20 #--*/
     21 #
     22 #include "EfiBind.h"
     23 #---------------------------------------------------------------------------
     24     .686:
     25     #.MODEL flat,C
     26     .code:
     27 
     28 #---------------------------------------------------------------------------
     29 .globl ASM_PFX(LShiftU64)
     30 #
     31 #UINT64
     32 #LShiftU64 (
     33 #  IN UINT64   Operand,
     34 #  IN UINTN    Count
     35 #  )
     36 #/*++
     37 #
     38 #Routine Description:
     39 #
     40 #  This routine allows a 64 bit value to be left shifted by 32 bits and
     41 #  returns the shifted value.
     42 #  Count is valid up 63. (Only Bits 0-5 is valid for Count)
     43 #
     44 #Arguments:
     45 #
     46 #  Operand - Value to be shifted
     47 #  Count   - Number of times to shift left.
     48 #
     49 #Returns:
     50 #
     51 #  Value shifted left identified by the Count.
     52 #
     53 #--*/
     54 ASM_PFX(LShiftU64):
     55 
     56     movl   4(%esp), %eax # dword ptr Operand[0]
     57     movl   8(%esp), %edx # dword ptr Operand[4]
     58 
     59     #
     60     # CL is valid from 0 - 31. shld will move EDX:EAX by CL times but EAX is not touched
     61     # For CL of 32 - 63, it will be shifted 0 - 31 so we will move eax to edx later.
     62     #
     63     movl   0xC(%esp), %ecx # Count
     64     andl   $63, %ecx
     65     shld   %cl, %eax, %edx
     66     shlb   %cl, %eax
     67 
     68     #
     69     # Since Count is 32 - 63, eax will have been shifted  by 0 - 31
     70     # If shifted by 32 or more, set lower 32 bits to zero.
     71     #
     72     cmpl   $32, %ecx
     73     jc     _LShiftU64_Done
     74 
     75     movl   %eax, %edx
     76     xorl   %eax, %eax
     77 
     78 _LShiftU64_Done:
     79 
     80     ret
     81 #LShiftU64 ENDP
     82 
     83