Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: BigIntSupport.pm | |
4 | # Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | # 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | # | |
7 | # * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | # | |
9 | # This program is free software; you can redistribute it and/or modify | |
10 | # it under the terms of the GNU General Public License as published by | |
11 | # the Free Software Foundation; version 2 of the License. | |
12 | # | |
13 | # This program is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with this program; if not, write to the Free Software | |
20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | # | |
22 | # For the avoidance of doubt, and except that if any non-GPL license | |
23 | # choice is available it will apply instead, Sun elects to use only | |
24 | # the General Public License version 2 (GPLv2) at this time for any | |
25 | # software where a choice of GPL license versions is made | |
26 | # available with the language indicating that GPLv2 or any later version | |
27 | # may be used, or where a choice of which version of the GPL is applied is | |
28 | # otherwise unspecified. | |
29 | # | |
30 | # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | # CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | # have any questions. | |
33 | # | |
34 | # ========== Copyright Header End ============================================ | |
35 | package BigIntSupport; | |
36 | ||
37 | require 5.005_62; | |
38 | use strict; | |
39 | use warnings; | |
40 | ||
41 | require Exporter; | |
42 | use Math::BigInt; | |
43 | use Carp; | |
44 | ||
45 | our @ISA = qw(Exporter); | |
46 | ||
47 | # Items to export into callers namespace by default. Note: do not export | |
48 | # names by default without a very good reason. Use EXPORT_OK instead. | |
49 | # Do not simply export all your public functions/methods/constants. | |
50 | ||
51 | # This allows declaration use BigIntSupport ':all'; | |
52 | # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK | |
53 | # will save memory. | |
54 | our %EXPORT_TAGS = ( 'all' => [ qw( | |
55 | ||
56 | ) ] ); | |
57 | ||
58 | our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); | |
59 | ||
60 | our @EXPORT = qw( | |
61 | hex2bigint | |
62 | bigint2hex | |
63 | bigint_sprintf | |
64 | ); | |
65 | our $VERSION = '1.01'; | |
66 | ||
67 | ||
68 | # Preloaded methods go here. | |
69 | ||
70 | sub hex2bigint { | |
71 | my $hexstring = shift; | |
72 | $hexstring = 0 unless defined $hexstring; | |
73 | $hexstring =~ s/^\s+//; | |
74 | $hexstring =~ s/\s+$//; | |
75 | $hexstring =~ s/^0[xX]//; | |
76 | ||
77 | my $bignum = Math::BigInt->new(0); | |
78 | my $shift = 0; | |
79 | ||
80 | while(length $hexstring) { | |
81 | my $tail = substr $hexstring, -8, 8, ""; | |
82 | my $tailval = hex($tail); | |
83 | $bignum += Math::BigInt->new($tailval) << $shift; | |
84 | $shift += 32; | |
85 | } | |
86 | ||
87 | return $bignum; | |
88 | } | |
89 | ||
90 | ||
91 | sub bigint2hex { | |
92 | my $bignum = shift; | |
93 | ||
94 | if(not ref $bignum) { | |
95 | return sprintf("%x", $bignum); | |
96 | } | |
97 | ||
98 | my $string = ""; | |
99 | ||
100 | while($bignum) { | |
101 | my $low = $bignum & 0xffffffff; | |
102 | $string = sprintf("%08x", $low) . $string; | |
103 | $bignum >>= 32; | |
104 | } | |
105 | $string =~ s/^0+//; | |
106 | ||
107 | $string = '0' if $string eq ''; | |
108 | ||
109 | return $string; | |
110 | } | |
111 | ||
112 | ||
113 | sub bigint_sprintf { | |
114 | my $bigint = shift; | |
115 | my $format = shift; | |
116 | ||
117 | if($format =~ /^\s*\%?(0)?(\d+)?[lL]*([xd])\s*/) { | |
118 | my ($lead, $width, $base) = ($1, $2, $3); | |
119 | ||
120 | $width = 0 unless defined $width; | |
121 | $base = '' unless defined $base; | |
122 | ||
123 | my $string; | |
124 | ||
125 | ||
126 | if($base eq 'd') { | |
127 | $string = "$bigint"; | |
128 | $string =~ s/^\+//; | |
129 | } else { | |
130 | $string = bigint2hex($bigint); | |
131 | } | |
132 | ||
133 | my $strlen = length($string); | |
134 | if($width > $strlen) { | |
135 | my $diff = $width - $strlen; | |
136 | my $char = defined($lead)? '0' : ' '; | |
137 | my $leading = $char x $diff; | |
138 | $string = "$leading$string"; | |
139 | } | |
140 | return $string; | |
141 | } else { | |
142 | croak "Bad format string: $format"; | |
143 | } | |
144 | } | |
145 | ||
146 | ||
147 | 1; | |
148 | __END__ | |
149 | # Below is stub documentation for your module. You better edit it! | |
150 | ||
151 | =head1 NAME | |
152 | ||
153 | BigIntSupport - Perl extension for interfacing between Math::BigInt values and text strings. | |
154 | ||
155 | =head1 SYNOPSIS | |
156 | ||
157 | use BigIntSupport; | |
158 | use Math::BigInt; | |
159 | ||
160 | # Create Math::BigInt from an arbitrary-sized hex number | |
161 | my $bigint1 = hex2bigint("0xdeadbeefcafebabe01234567"); | |
162 | my $bigint2 = hex2bigint("0xffffffff"); | |
163 | # Do math | |
164 | $bigint2 <<= 32; | |
165 | $bigint1 &= $bigint2; | |
166 | # Get hex string back | |
167 | my $string = bigint2hex($bigint1); | |
168 | # Print it | |
169 | print "Result is 0x$string\n"; | |
170 | ||
171 | ||
172 | =head1 DESCRIPTION | |
173 | ||
174 | This provides some interface functions for the Math::BigInt library, | |
175 | which is part of the perl standard libary. Basically, Math::BigInt is | |
176 | a module for arbitrary-sized integers. It overloads all the standard | |
177 | math operators for use with Math::BigInt objects, but it does not | |
178 | overload either the hex() function or sprintf "%x", so it is difficult | |
179 | to use Math::BigInt objects for large hex numbers. This module is a | |
180 | solution to that problem. | |
181 | ||
182 | =head2 EXPORT | |
183 | ||
184 | The following functions are exported: | |
185 | ||
186 | =over 4 | |
187 | ||
188 | =item hex2bigint($hex_string) | |
189 | ||
190 | Interprets $hex_string as a hex number (whether or not a leading 0x is | |
191 | present). Returns a Math::BigInt object representing the number. To | |
192 | convert decimal numbers to Math::BigInt objects, use | |
193 | Math::BigInt->new($decimal_string). | |
194 | ||
195 | =item bigint2hex($bigint) | |
196 | ||
197 | Formats the given Math::BigInt object as a hexidecimal string and | |
198 | returns it. The string has no leading zeros or 0x. | |
199 | ||
200 | =item bigint_sprintf($bigint, $format) | |
201 | ||
202 | Takes a Math::BigInt and a printf-style format string and returns a | |
203 | string with the appropriately-formatted string. The format string can | |
204 | contain only %x or %d, and may optionally include a width | |
205 | specification, which may include a leading zero. In other words, | |
206 | "%016x" is legal but "The answer is %d" is not. A leading "%" is | |
207 | optional. | |
208 | ||
209 | =back | |
210 | ||
211 | ||
212 | ||
213 | =head1 SEE ALSO | |
214 | ||
215 | Math::BigInt(3), perl(1). | |
216 | ||
217 | =cut |