blob: 9ee40efa41d8a8e01f8ec0199a01750f71125303 [file] [log] [blame]
Vadim Bendeburycb8f3602014-08-25 17:45:57 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google, Inc.
5 *
6 * Based on linux arch/mips/lib/ashldi3.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Vadim Bendeburycb8f3602014-08-25 17:45:57 -070016 */
17
18#ifndef __ORDER_LITTLE_ENDIAN__
19#errror "What endian are you!?"
20#endif
21
22typedef unsigned word_type;
23long long __ashldi3(long long u, word_type b);
24
25struct DWstruct {
26 int low, high;
27};
28typedef union {
29 struct DWstruct s;
30 long long ll;
31} DWunion;
32
33long long __ashldi3(long long u, word_type b)
34{
35 DWunion uu, w;
36 word_type bm;
37
38 if (b == 0)
39 return u;
40
41 uu.ll = u;
42 bm = 32 - b;
43
44 if (bm <= 0) {
45 w.s.low = 0;
46 w.s.high = (unsigned int) uu.s.low << -bm;
47 } else {
48 const unsigned int carries = (unsigned int) uu.s.low >> bm;
49
50 w.s.low = (unsigned int) uu.s.low << b;
51 w.s.high = ((unsigned int) uu.s.high << b) | carries;
52 }
53
54 return w.ll;
55}