File : s-gccshi.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y S T E M . G C C . S H I F T S --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2013-2014, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
17 -- --
18 -- --
19 -- --
20 -- --
21 -- --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
26 -- --
27 -- GNAT was originally developed by the GNAT team at New York University. --
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
31
32 package body System.GCC.Shifts is
33 use Interfaces;
34
35 -------------
36 -- Lshrdi3 --
37 -------------
38
39 function Lshrdi3 (Val : Unsigned_64; Count : Integer) return Unsigned_64 is
40 Hi, Lo : Unsigned_32;
41 Carries : Unsigned_32;
42
43 begin
44 Split (Val, Hi, Lo);
45
46 case Count is
47 when 64 .. Integer'Last =>
48 return 0;
49
50 when 32 .. 63 =>
51 return Unsigned_64 (Shift_Right (Hi, Count - 32));
52
53 when 1 .. 31 =>
54 Carries := Shift_Left (Hi, 32 - Count);
55 Hi := Shift_Right (Hi, Count);
56 Lo := Shift_Right (Lo, Count) or Carries;
57 return Merge (Hi, Lo);
58
59 when Integer'First .. 0 =>
60 return Val;
61 end case;
62 end Lshrdi3;
63
64 -------------
65 -- Ashrdi3 --
66 -------------
67
68 function Ashrdi3 (Val : Unsigned_64; Count : Integer) return Unsigned_64 is
69 Hi, Lo : Unsigned_32;
70 Carries : Unsigned_32;
71
72 begin
73 Split (Val, Hi, Lo);
74
75 case Count is
76 when 64 .. Integer'Last =>
77 Hi := Shift_Right_Arithmetic (Hi, 31);
78 return Merge (Hi, Hi);
79
80 when 32 .. 63 =>
81 Lo := Shift_Right_Arithmetic (Hi, Count - 32);
82 Hi := Shift_Right_Arithmetic (Hi, 31);
83 return Merge (Hi, Lo);
84
85 when 1 .. 31 =>
86 Carries := Shift_Left (Hi, 32 - Count);
87 Hi := Shift_Right_Arithmetic (Hi, Count);
88 Lo := Shift_Right (Lo, Count) or Carries;
89 return Merge (Hi, Lo);
90
91 when Integer'First .. 0 =>
92 return Val;
93 end case;
94 end Ashrdi3;
95
96 -------------
97 -- Ashldi3 --
98 -------------
99
100 function Ashldi3 (Val : Unsigned_64; Count : Integer) return Unsigned_64 is
101 Hi, Lo : Unsigned_32;
102 Carries : Unsigned_32;
103
104 begin
105 Split (Val, Hi, Lo);
106
107 case Count is
108 when 64 .. Integer'Last =>
109 return 0;
110
111 when 32 .. 63 =>
112 return Merge (Shift_Left (Lo, Count - 32), 0);
113
114 when 1 .. 31 =>
115 Carries := Shift_Right (Lo, 32 - Count);
116 Lo := Shift_Left (Lo, Count);
117 Hi := Shift_Left (Hi, Count) or Carries;
118 return Merge (Hi, Lo);
119
120 when Integer'First .. 0 =>
121 return Val;
122 end case;
123 end Ashldi3;
124
125 end System.GCC.Shifts;