3 .\" Copyright (C) 2003-2018 Free Software Foundation, Inc.
4 .\" Written by Werner Lemberg (wl@gnu.org)
6 .\" This file is part of groff.
8 .\" groff is free software; you can redistribute it and/or modify it
9 .\" under the terms of the GNU General Public License as published by
10 .\" the Free Software Foundation, either version 3 of the License, or
11 .\" (at your option) any later version.
13 .\" groff is distributed in the hope that it will be useful, but WITHOUT
14 .\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 .\" or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 .\" License for more details.
18 .\" You should have received a copy of the GNU General Public License
19 .\" along with this program. If not, see
20 .\" <http://www.gnu.org/licenses/>.
23 .\" This file provides macros for addition, multiplication, and division
24 .\" of 62-bit signed integers. Its main application is to 'scale'
25 .\" 31-bit values--namely, to perform the operation 'a * b / c'
28 .\" Note that it is the duty of the user to check whether the input
29 .\" values fit within 31 bits (this is the range
30 .\" [-1073741824,1073741823]).
37 .\" .add31to62 <x> <y> <z>
39 .\" Add a 31-bit signed integer to a signed 62-bit integer. Result is a
40 .\" signed 62-bit integer:
42 .\" <x> + (<y>h * 2^30 + <y>l) = <z>h * 2^30 + <z>l
45 .\" in: \n[<x>], \n[<y>h], \n[<y>l]
47 .\" out: \n[<z>h], \n[<z>l]
49 .\" Example: .add31to62 p q r
51 .\" -> input registers: \n[p], \n[qh], \n[ql]
52 .\" output registers: \n[rh], \n[rl]
55 . nr 62bit-lo2 (\\n[\\$2l])
56 . nr 62bit-hi2 (\\n[\\$2h])
58 . nr 62bit-i ((\\n[\\$1] + \\n[62bit-lo2]) / 1073741824)
59 . nr \\$3l ((\\n[\\$1] + \\n[62bit-lo2]) % 1073741824)
61 . ie ((\\n[62bit-lo2] > 0) & (\\n[\\$3l] < 0)) \{\
62 . nr \\$3l +1073741824
66 . if ((\\n[62bit-lo2] < 0) & (\\n[\\$3l] > 0)) \{\
67 . nr \\$3l -1073741824
71 . nr \\$3h (\\n[62bit-hi2] + \\n[62bit-i])
75 .\" .mult31by31 <x> <y> <z>
77 .\" Multiply two 31-bit signed integers. Result is a 62-bit signed
80 .\" <x> * <y> = <z>h * 2^30 + <z>l
83 .\" in: \n[<x>], \n[<y>]
85 .\" out: \n[<z>h], \n[<z>l]
87 .\" Example: .mult31by31 a b c
89 .\" -> input registers: \n[a], \n[b]
90 .\" output registers: \n[ch], \n[cl]
93 . nr 62bit-1 (\\n[\\$1])
94 . nr 62bit-2 (\\n[\\$2])
97 . if !\\n[62bit-1] \{\
98 . nr 62bit-sign -(\\n[62bit-sign])
99 . nr 62bit-1 -(\\n[62bit-1])
101 . if !\\n[62bit-2] \{\
102 . nr 62bit-sign -(\\n[62bit-sign])
103 . nr 62bit-2 -(\\n[62bit-2])
106 . nr 62bit-lo1 (\\n[62bit-1] % 32768)
107 . nr 62bit-hi1 (\\n[62bit-1] / 32768)
108 . nr 62bit-lo2 (\\n[62bit-2] % 32768)
109 . nr 62bit-hi2 (\\n[62bit-2] / 32768)
111 . nr 62bit-lo3 (\\n[62bit-lo1] * \\n[62bit-lo2] % 1073741824)
112 . nr 62bit-i1 (\\n[62bit-lo1] * \\n[62bit-hi2] % 1073741824)
113 . nr 62bit-i2 (\\n[62bit-lo2] * \\n[62bit-hi1] % 1073741824)
114 . nr 62bit-hi3 (\\n[62bit-hi1] * \\n[62bit-hi2] % 1073741824)
116 . nr 62bit-i1 (\\n[62bit-i1] + \\n[62bit-i2] % 1073741824)
117 . \" check carry overflow of 62bit-i1 + 62bit-i2
118 . if (\\n[62bit-i1] < \\n[62bit-i2]) \
119 . nr 62bit-hi3 +32768
121 . nr 62bit-hi3 +(\\n[62bit-i1] / 32768)
122 . \" multiply by 32768 in small steps to avoid overflow
124 . while \\n-[62bit-i] \
125 . nr 62bit-i1 (\\n[62bit-i1] * 2 % 1073741824)
127 . nr 62bit-lo3 (\\n[62bit-lo3] + \\n[62bit-i1] % 1073741824)
128 . \" check carry overflow of 62bit-i1 + lo
129 . if (\\n[62bit-lo3] < \\n[62bit-i1]) \
132 . if !\\n[62bit-sign] \{\
133 . nr 62bit-lo3 -(\\n[62bit-lo3])
134 . nr 62bit-hi3 -(\\n[62bit-hi3])
136 . nr \\$3l \\n[62bit-lo3]
137 . nr \\$3h \\n[62bit-hi3]
141 .\" .div62by31 <x> <y> <z>
143 .\" Divide a signed 62-bit integer by a 31-bit integer. Result is a
144 .\" 31-bit signed integer:
146 .\" (<x>h * 2^30 + <x>l) / <y> = <z>
149 .\" in: \n[<x>h], \n[<x>l], \n[<y>]
153 .\" Example: .div62by31 foo bar baz
155 .\" -> input registers: \n[fooh] \n[fool] \n[bar]
156 .\" output register: \n[baz]
159 . nr 62bit-lo1 \\n[\\$1l]
160 . nr 62bit-hi1 \\n[\\$1h]
161 . nr 62bit-2 \\n[\\$2]
165 . if ((\\n[62bit-lo1] < 0) : (\\n[62bit-hi1] < 0)) \{\
166 . nr 62bit-sign -(\\n[62bit-sign])
167 . nr 62bit-lo1 -(\\n[62bit-lo1])
168 . nr 62bit-hi1 -(\\n[62bit-hi1])
170 . if !\\n[62bit-2] \{\
171 . nr 62bit-sign -(\\n[62bit-sign])
172 . nr 62bit-2 -(\\n[62bit-2])
176 . while \\n-[62bit-i] \{\
177 . nr 62bit-hi1 (\\n[62bit-hi1] * 2 % 1073741824)
178 . nr 62bit-3 (\\n[62bit-3] * 2)
179 . nr 62bit-hi1 +(\\n[62bit-lo1] / 536870912)
181 . if (\\n[62bit-hi1] >= \\n[62bit-2]) \{\
182 . nr 62bit-hi1 -\\n[62bit-2]
185 . nr 62bit-lo1 (\\n[62bit-lo1] * 2 % 1073741824)
188 . if !\\n[62bit-sign] \
189 . nr 62bit-3 -(\\n[62bit-3])
190 . nr \\$3 \\n[62bit-3]
193 .\" ====================================================================
195 .\" ====================================================================
201 .\" vim: set filetype=groff textwidth=72: