Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/picochip/libgccExtras/ashrsi3.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | f6334be47118 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* | |
2 | |
3 picoChip GCC support for 32-bit arithmetic shift right. | |
4 | |
5 Copyright (C) 2003, 2004, 2005, 2008, 2009 Free Software Foundation, Inc. | |
6 Contributed by picoChip Designs Ltd. | |
7 Maintained by Daniel Towner (daniel.towner@picochip.com) | |
8 | |
9 This file is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 3, or (at your option) any | |
12 later version. | |
13 | |
14 This file is distributed in the hope that it will be useful, but | |
15 WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 General Public License for more details. | |
18 | |
19 Under Section 7 of GPL version 3, you are granted additional | |
20 permissions described in the GCC Runtime Library Exception, version | |
21 3.1, as published by the Free Software Foundation. | |
22 | |
23 You should have received a copy of the GNU General Public License and | |
24 a copy of the GCC Runtime Library Exception along with this program; | |
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see | |
26 <http://www.gnu.org/licenses/>. */ | |
27 | |
28 typedef int HItype __attribute__ ((mode (HI))); | |
29 typedef unsigned int UHItype __attribute__ ((mode (HI))); | |
30 typedef unsigned int USItype __attribute__ ((mode (SI))); | |
31 | |
32 typedef struct USIstruct { | |
33 UHItype low, high; | |
34 } USIstruct; | |
35 | |
36 typedef union USIunion { | |
37 USItype l; | |
38 USIstruct s; | |
39 } USIunion; | |
40 | |
41 USItype __ashrsi3(USIunion value, HItype count) { | |
42 USIunion result; | |
43 int temp; | |
44 int wordOfSignBits; | |
45 | |
46 /* Ignore a zero count until we get into the (count < 16) | |
47 clause. This is slightly slower when shifting by zero, but faster | |
48 and smaller in all other cases (due to the better scheduling | |
49 opportunities available by putting the test near computational | |
50 instructions. */ | |
51 /* if (count == 0) return value.l; */ | |
52 | |
53 if (count < 16) { | |
54 /* Shift low and high words by the count. The high word must use | |
55 an arithmetic shift. There is no arithmetic shift-right by | |
56 variable, so synthesise it. */ | |
57 int signWord; | |
58 int reverseCount; | |
59 | |
60 /* Shift low and high parts by the count. The upper word now has | |
61 invalid signed bits. */ | |
62 result.s.low = value.s.low >> count; | |
63 result.s.high = value.s.high >> count; | |
64 | |
65 if (count != 0) { | |
66 | |
67 reverseCount = 16 - count; | |
68 | |
69 /* Given a word of sign bits, shift back left to create the | |
70 destination sign bits. */ | |
71 wordOfSignBits = __builtin_asri(value.s.high, 15); | |
72 signWord = wordOfSignBits << reverseCount; | |
73 result.s.high |= signWord; | |
74 | |
75 /* There is now a hole in the upper `count' bits of the low | |
76 word. Shift the lower `count' bits of the upper word into the | |
77 low word. */ | |
78 temp = value.s.high << reverseCount; | |
79 result.s.low |= temp; | |
80 } | |
81 | |
82 } else { | |
83 int signWord; | |
84 | |
85 /* Shift is greater than one word, so top word will always be set | |
86 to sign bits, and bottom word will be shifted from top word. */ | |
87 result.s.low = value.s.high >> count; | |
88 result.s.high = __builtin_asri(value.s.high, 15); | |
89 | |
90 if (count != 16) { | |
91 | |
92 /* Shift the upper word of the source into the lower word of the | |
93 result. Arithmetically shift the upper word as well, to retain | |
94 the sign. This shift must be synthesised, as no such shift | |
95 exists in the instruction set. */ | |
96 int signWord; | |
97 | |
98 | |
99 /* Given a complete word of sign-bits, shift this back left to | |
100 create the destination sign bits. */ | |
101 signWord = result.s.high << (16 - count); | |
102 // signWord = wordOfSignBits << (16 - count); | |
103 | |
104 /* Insert the sign bits to the result's low word. */ | |
105 result.s.low |= signWord; | |
106 | |
107 } | |
108 | |
109 } | |
110 | |
111 return result.l; | |
112 | |
113 } |