2 .\"@ This file provides macros for addition, multiplication, and division of
3 .\"@ 62bit signed integers. Its main application is to `scale' 31bit values,
4 .\"@ namely, to perform the operation `a * b / c' accurately.
6 .\"@ Note that it is the duty of the user to check whether the input values
7 .\"@ fit within 31 bits (this is the range [-1073741824,1073741823]).
9 .\" Copyright (c) 2014 - 2017 Steffen (Daode) Nurpmeso <steffen@sdaoden.eu>.
11 .\" Copyright (C) 2003, 2006
12 .\" Free Software Foundation, Inc.
13 .\" Written by Werner Lemberg (wl@gnu.org)
15 .\" This is free software; you can redistribute it and/or modify it under
16 .\" the terms of the GNU General Public License as published by the Free
17 .\" Software Foundation; either version 2, or (at your option) any later
20 .\" This is distributed in the hope that it will be useful, but WITHOUT ANY
21 .\" WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 .\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 .\" You should have received a copy of the GNU General Public License along
26 .\" with groff; see the file COPYING. If not, write to the Free Software
27 .\" Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA.
33 .\" .add31to62 <x> <y> <z>
35 .\" Add a 31bit signed integer to a signed 62bit integer. Result is a
36 .\" signed 62bit integer:
38 .\" <x> + (<y>h * 2^30 + <y>l) = <z>h * 2^30 + <z>l
41 .\" in: \n[<x>], \n[<y>h], \n[<y>l]
43 .\" out: \n[<z>h], \n[<z>l]
45 .\" Example: .add31to62 p q r
47 .\" -> input registers: \n[p], \n[qh], \n[ql]
48 .\" output registers: \n[rh], \n[rl]
51 . nr 62bit-lo2 (\\n[\\$2l])
52 . nr 62bit-hi2 (\\n[\\$2h])
54 . nr 62bit-i ((\\n[\\$1] + \\n[62bit-lo2]) / 1073741824)
55 . nr \\$3l ((\\n[\\$1] + \\n[62bit-lo2]) % 1073741824)
57 . ie ((\\n[62bit-lo2] > 0) & (\\n[\\$3l] < 0)) \{\
58 . nr \\$3l +1073741824
62 . if ((\\n[62bit-lo2] < 0) & (\\n[\\$3l] > 0)) \{\
63 . nr \\$3l -1073741824
67 . nr \\$3h (\\n[62bit-hi2] + \\n[62bit-i])
71 .\" .mult31by31 <x> <y> <z>
73 .\" Multiply two 31bit signed integers. Result is a 62bit signed
76 .\" <x> * <y> = <z>h * 2^30 + <z>l
79 .\" in: \n[<x>], \n[<y>]
81 .\" out: \n[<z>h], \n[<z>l]
83 .\" Example: .mult31by31 a b c
85 .\" -> input registers: \n[a], \n[b]
86 .\" output registers: \n[ch], \n[cl]
89 . nr 62bit-1 (\\n[\\$1])
90 . nr 62bit-2 (\\n[\\$2])
93 . if !\\n[62bit-1] \{\
94 . nr 62bit-sign -(\\n[62bit-sign])
95 . nr 62bit-1 -(\\n[62bit-1])
97 . if !\\n[62bit-2] \{\
98 . nr 62bit-sign -(\\n[62bit-sign])
99 . nr 62bit-2 -(\\n[62bit-2])
102 . nr 62bit-lo1 (\\n[62bit-1] % 32768)
103 . nr 62bit-hi1 (\\n[62bit-1] / 32768)
104 . nr 62bit-lo2 (\\n[62bit-2] % 32768)
105 . nr 62bit-hi2 (\\n[62bit-2] / 32768)
107 . nr 62bit-lo3 (\\n[62bit-lo1] * \\n[62bit-lo2] % 1073741824)
108 . nr 62bit-i1 (\\n[62bit-lo1] * \\n[62bit-hi2] % 1073741824)
109 . nr 62bit-i2 (\\n[62bit-lo2] * \\n[62bit-hi1] % 1073741824)
110 . nr 62bit-hi3 (\\n[62bit-hi1] * \\n[62bit-hi2] % 1073741824)
112 . nr 62bit-i1 (\\n[62bit-i1] + \\n[62bit-i2] % 1073741824)
113 . \" check carry overflow of 62bit-i1 + 62bit-i2
114 . if (\\n[62bit-i1] < \\n[62bit-i2]) \
115 . nr 62bit-hi3 +32768
117 . nr 62bit-hi3 +(\\n[62bit-i1] / 32768)
118 . \" multiply by 32768 in small steps to avoid overflow
120 . while \\n-[62bit-i] \
121 . nr 62bit-i1 (\\n[62bit-i1] * 2 % 1073741824)
123 . nr 62bit-lo3 (\\n[62bit-lo3] + \\n[62bit-i1] % 1073741824)
124 . \" check carry overflow of 62bit-i1 + lo
125 . if (\\n[62bit-lo3] < \\n[62bit-i1]) \
128 . if !\\n[62bit-sign] \{\
129 . nr 62bit-lo3 -(\\n[62bit-lo3])
130 . nr 62bit-hi3 -(\\n[62bit-hi3])
132 . nr \\$3l \\n[62bit-lo3]
133 . nr \\$3h \\n[62bit-hi3]
137 .\" .div62by31 <x> <y> <z>
139 .\" Divide a signed 62bit integer by a 31bit integer. Result is a
140 .\" 31bit signed integer:
142 .\" (<x>h * 2^30 + <x>l) / <y> = <z>
145 .\" in: \n[<x>h], \n[<x>l], \n[<y>]
149 .\" Example: .div62by31 foo bar baz
151 .\" -> input registers: \n[fooh] \n[fool] \n[bar]
152 .\" output register: \n[baz]
155 . nr 62bit-lo1 \\n[\\$1l]
156 . nr 62bit-hi1 \\n[\\$1h]
157 . nr 62bit-2 \\n[\\$2]
161 . if ((\\n[62bit-lo1] < 0) : (\\n[62bit-hi1] < 0)) \{\
162 . nr 62bit-sign -(\\n[62bit-sign])
163 . nr 62bit-lo1 -(\\n[62bit-lo1])
164 . nr 62bit-hi1 -(\\n[62bit-hi1])
166 . if !\\n[62bit-2] \{\
167 . nr 62bit-sign -(\\n[62bit-sign])
168 . nr 62bit-2 -(\\n[62bit-2])
172 . while \\n-[62bit-i] \{\
173 . nr 62bit-hi1 (\\n[62bit-hi1] * 2 % 1073741824)
174 . nr 62bit-3 (\\n[62bit-3] * 2)
175 . nr 62bit-hi1 +(\\n[62bit-lo1] / 536870912)
177 . if (\\n[62bit-hi1] >= \\n[62bit-2]) \{\
178 . nr 62bit-hi1 -\\n[62bit-2]
181 . nr 62bit-lo1 (\\n[62bit-lo1] * 2 % 1073741824)
184 . if !\\n[62bit-sign] \
185 . nr 62bit-3 -(\\n[62bit-3])
186 . nr \\$3 \\n[62bit-3]