xref: /optee_os/lib/libutils/isoc/arch/arm/arm32_aeabi_shift.c (revision 78b7c7c7653f8bff42fe44d31a79d7f6bbfd4d47)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2015, Linaro Limited
4  * All rights reserved.
5  */
6 
7 union dword {
8 	unsigned long long dw;
9 	unsigned long w[2];
10 };
11 
12 long long __aeabi_llsl(long long a, int shift);
13 long long __aeabi_llsl(long long a, int shift)
14 {
15 	union dword dword = { .dw = a };
16 	unsigned long hi = dword.w[1];
17 	unsigned long lo = dword.w[0];
18 
19 	if (shift >= 32) {
20 		hi = lo << (shift - 32);
21 		lo = 0;
22 	} else if (shift > 0) {
23 		hi = (hi << shift) | (lo >> (32 - shift));
24 		lo = lo << shift;
25 	}
26 
27 	dword.w[1] = hi;
28 	dword.w[0] = lo;
29 	return dword.dw;
30 }
31 
32 long long __aeabi_llsr(long long a, int shift);
33 long long __aeabi_llsr(long long a, int shift)
34 {
35 	union dword dword = { .dw = a };
36 	unsigned long hi = dword.w[1];
37 	unsigned long lo = dword.w[0];
38 
39 	if (shift >= 32) {
40 		lo = hi >> (shift - 32);
41 		hi = 0;
42 	} else if (shift > 0) {
43 		lo = (lo >> shift) | (hi << (32 - shift));
44 		hi = hi >> shift;
45 	}
46 
47 	dword.w[1] = hi;
48 	dword.w[0] = lo;
49 	return dword.dw;
50 }
51