]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/intrinsics/ishftc.c
Update copyright years.
[thirdparty/gcc.git] / libgfortran / intrinsics / ishftc.c
CommitLineData
6de9cd9a 1/* Implementation of ishftc intrinsic.
8d9254fc 2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
6de9cd9a
DN
3 Contributed by Paul Brook <paul@nowt.org>
4
57dea9f6 5This file is part of the GNU Fortran 95 runtime library (libgfortran).
6de9cd9a
DN
6
7Libgfortran is free software; you can redistribute it and/or
57dea9f6 8modify it under the terms of the GNU General Public
6de9cd9a 9License as published by the Free Software Foundation; either
748086b7 10version 3 of the License, or (at your option) any later version.
6de9cd9a
DN
11
12Libgfortran is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57dea9f6 15GNU General Public License for more details.
6de9cd9a 16
748086b7
JJ
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
6de9cd9a
DN
25
26#include "libgfortran.h"
27
7d7b8bfe
RH
28extern GFC_INTEGER_4 ishftc4 (GFC_INTEGER_4, GFC_INTEGER_4, GFC_INTEGER_4);
29export_proto(ishftc4);
6de9cd9a
DN
30
31GFC_INTEGER_4
32ishftc4 (GFC_INTEGER_4 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
33{
c152efbb 34 GFC_UINTEGER_4 mask, bits;
6de9cd9a
DN
35
36 if (shift < 0)
37 shift = shift + size;
38
39 if (shift == 0 || shift == size)
40 return i;
41
c152efbb
JD
42 /* In C, the result of the shift operator is undefined if the right operand
43 is greater than or equal to the number of bits in the left operand. So we
44 have to special case it for fortran. */
45 mask = ~((size == 32) ? (GFC_UINTEGER_4)0 : (~(GFC_UINTEGER_4)0 << size));
46
47 bits = i & mask;
48
49 return (i & ~mask) | ((bits << shift) & mask) | (bits >> (size - shift));
6de9cd9a
DN
50}
51
56746a07 52extern GFC_INTEGER_8 ishftc8 (GFC_INTEGER_8, GFC_INTEGER_4, GFC_INTEGER_4);
7d7b8bfe 53export_proto(ishftc8);
6de9cd9a
DN
54
55GFC_INTEGER_8
56746a07 56ishftc8 (GFC_INTEGER_8 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
6de9cd9a 57{
c152efbb 58 GFC_UINTEGER_8 mask, bits;
6de9cd9a
DN
59
60 if (shift < 0)
61 shift = shift + size;
62
63 if (shift == 0 || shift == size)
64 return i;
65
c152efbb
JD
66 /* In C, the result of the shift operator is undefined if the right operand
67 is greater than or equal to the number of bits in the left operand. So we
68 have to special case it for fortran. */
69 mask = ~((size == 64) ? (GFC_UINTEGER_8)0 : (~(GFC_UINTEGER_8)0 << size));
70
71 bits = i & mask;
72
73 return (i & ~mask) | ((bits << shift) & mask) | (bits >> (size - shift));
6de9cd9a 74}
644cb69f
FXC
75
76#ifdef HAVE_GFC_INTEGER_16
77extern GFC_INTEGER_16 ishftc16 (GFC_INTEGER_16, GFC_INTEGER_4, GFC_INTEGER_4);
78export_proto(ishftc16);
79
80GFC_INTEGER_16
81ishftc16 (GFC_INTEGER_16 i, GFC_INTEGER_4 shift, GFC_INTEGER_4 size)
82{
c152efbb 83 GFC_UINTEGER_16 mask, bits;
644cb69f
FXC
84
85 if (shift < 0)
86 shift = shift + size;
87
88 if (shift == 0 || shift == size)
89 return i;
90
c152efbb
JD
91 /* In C, the result of the shift operator is undefined if the right operand
92 is greater than or equal to the number of bits in the left operand. So we
93 have to special case it for fortran. */
94 mask = ~((size == 128) ? (GFC_UINTEGER_16)0 : (~(GFC_UINTEGER_16)0 << size));
95
96 bits = i & mask;
97
98 return (i & ~mask) | ((bits << shift) & mask) | (bits >> (size - shift));
644cb69f
FXC
99}
100#endif