Software APIs
math_unittest.cc
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
6 
7 #include <ostream>
8 #include <stdint.h>
9 #include <tuple>
10 
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
13 
14 namespace math_unittest {
15 namespace {
16 
17 struct DivVector {
18  uint64_t a, b, q, r;
19 
20  friend void operator<<(std::ostream &out, const DivVector &v) {
21  out << "{" << v.a << ", " << v.b << ", " << v.q << ", " << v.r << "}";
22  }
23 };
24 
25 class UDivTest : public testing::TestWithParam<DivVector> {};
26 
27 TEST_P(UDivTest, UDiv64) {
28  uint64_t rem;
29  EXPECT_EQ(udiv64_slow(GetParam().a, GetParam().b, &rem), GetParam().q);
30  EXPECT_EQ(rem, GetParam().r);
31 }
32 
33 // Simple python snippet for generating vectors:
34 //
35 // import random
36 // # Full division.
37 // for _ in range(0, 32):
38 // a, b = random.getrandbits(64), random.getrandbits(64)
39 // print(f"{{{a}ull, {b}ull, {a//b}ull, {a%b}ull}},")
40 //
41 // # Div by u48
42 // for _ in range(0, 32):
43 // a, b = random.getrandbits(64), random.getrandbits(48)
44 // print(f"{{{a}ull, {b}ull, {a//b}ull, {a%b}ull}},")
45 //
46 // # Div by u32
47 // for _ in range(0, 32):
48 // a, b = random.getrandbits(64), random.getrandbits(32)
49 // print(f"{{{a}ull, {b}ull, {a//b}ull, {a%b}ull}},")
50 //
51 // # Product of u32s.
52 // for _ in range(0, 32):
53 // b, q = random.getrandbits(32), random.getrandbits(32)
54 // print(f"{{{b*q}ull, {b}ull, {q}ull, 0}},")
55 //
56 // clang-format off
57 constexpr DivVector kDivVectors[] = {
58  {16547064864992412266ull, 15362666177494521751ull, 1ull, 1184398687497890515ull},
59  {15117832593278048550ull, 9509133006104311255ull, 1ull, 5608699587173737295ull},
60  {7700533544865790561ull, 16200507889521424080ull, 0ull, 7700533544865790561ull},
61  {15751090594484430019ull, 4841336985583654393ull, 3ull, 1227079637733466840ull},
62  {1569256689953856309ull, 15136191600906927243ull, 0ull, 1569256689953856309ull},
63  {11646355910642376023ull, 16233286557913565679ull, 0ull, 11646355910642376023ull},
64  {11467848857967805770ull, 15343115856225830326ull, 0ull, 11467848857967805770ull},
65  {7082930862597735748ull, 13044336721903538272ull, 0ull, 7082930862597735748ull},
66  {7440142190527596899ull, 10232543569022431683ull, 0ull, 7440142190527596899ull},
67  {6162319322407126380ull, 14510700894994718373ull, 0ull, 6162319322407126380ull},
68  {11421574008009519807ull, 3446073093067775855ull, 3ull, 1083354728806192242ull},
69  {13590081538404264686ull, 5283212502034404741ull, 2ull, 3023656534335455204ull},
70  {14232045355477928062ull, 539825197847590283ull, 26ull, 196590211440580704ull},
71  {12580731027378952841ull, 16693509274214597629ull, 0ull, 12580731027378952841ull},
72  {17671460965360506731ull, 11247238544147177319ull, 1ull, 6424222421213329412ull},
73  {9664461898672776233ull, 9295631859719160580ull, 1ull, 368830038953615653ull},
74  {11015643691959628501ull, 11371567295203483667ull, 0ull, 11015643691959628501ull},
75  {8617136599055270914ull, 14553847862380133083ull, 0ull, 8617136599055270914ull},
76  {17480416258340506086ull, 5930856364822663088ull, 2ull, 5618703528695179910ull},
77  {14301781298682298274ull, 13686260976492283484ull, 1ull, 615520322190014790ull},
78  {12717390489997499836ull, 12396402423110714892ull, 1ull, 320988066886784944ull},
79  {9478693902079965650ull, 13922637938150164298ull, 0ull, 9478693902079965650ull},
80  {2218148139848502258ull, 16575500956377955560ull, 0ull, 2218148139848502258ull},
81  {6715234203200040462ull, 7716128746410333163ull, 0ull, 6715234203200040462ull},
82  {10620210067079001965ull, 2822959022621217088ull, 3ull, 2151332999215350701ull},
83  {14376175987504050882ull, 9698201778735636497ull, 1ull, 4677974208768414385ull},
84  {17907411000270102820ull, 4932086816672498435ull, 3ull, 3111150550252607515ull},
85  {2009523729344663635ull, 9177774962461691174ull, 0ull, 2009523729344663635ull},
86  {7794275604495320889ull, 17051579788896461924ull, 0ull, 7794275604495320889ull},
87  {1908688452509192803ull, 9477953155444810610ull, 0ull, 1908688452509192803ull},
88  {9865370653618144874ull, 2917100723726114133ull, 3ull, 1114068482439802475ull},
89  {14868378943466010358ull, 6893180186547617045ull, 2ull, 1082018570370776268ull},
90 
91  {15589205337902788058ull, 113947965797624ull, 136809ull, 98085095646242ull},
92  {154443034356190258ull, 212455867024500ull, 726ull, 200074896403258ull},
93  {14373381053726099454ull, 73780700389417ull, 194812ull, 15249462994850ull},
94  {12817128855238948341ull, 281345225603344ull, 45556ull, 165757653009077ull},
95  {6160912619711259892ull, 28980646173628ull, 212587ull, 3991598204256ull},
96  {15269508067345212820ull, 45485386217644ull, 335701ull, 18428695904376ull},
97  {7988213334521806465ull, 80165028719043ull, 99647ull, 8717755328644ull},
98  {17258038462583660946ull, 251077212750735ull, 68735ull, 246244161890721ull},
99  {1207754801805538860ull, 263416992465745ull, 4584ull, 251308342563780ull},
100  {8563707882399609092ull, 165228409036947ull, 51829ull, 84670423683029ull},
101  {746182492253572191ull, 195673554129159ull, 3813ull, 79230359088924ull},
102  {8496739951993591715ull, 228035340749822ull, 37260ull, 143155655223995ull},
103  {17292881127045336612ull, 248845483734607ull, 69492ull, 110771360026968ull},
104  {12005998103417887352ull, 252693626264731ull, 47512ull, 18532327988080ull},
105  {13076033720356300636ull, 69662783623236ull, 187704ull, 50583140410492ull},
106  {13331639988452463714ull, 232041084383213ull, 57453ull, 183567383727225ull},
107  {11740525896774895061ull, 142808904399401ull, 82211ull, 63057195739450ull},
108  {17175044619609759631ull, 158020044602567ull, 108689ull, 3991801354968ull},
109  {11951085009197228545ull, 189341158583116ull, 63119ull, 60420589529741ull},
110  {17835462114951798285ull, 162607057461277ull, 109684ull, 69624369091817ull},
111  {6950646436399140076ull, 14758119174077ull, 470971ull, 290864921309ull},
112  {6726003104404773273ull, 270548366585651ull, 24860ull, 170711085489413ull},
113  {6399411722239535722ull, 266575135796259ull, 24006ull, 9012314542168ull},
114  {13670372028797309326ull, 245433997117396ull, 55698ull, 189257352586918ull},
115  {4411737990115626057ull, 46185890582147ull, 95521ull, 15535818362470ull},
116  {6658768816131697888ull, 128030080935156ull, 52009ull, 52336775169484ull},
117  {7484953986642594286ull, 222513489770074ull, 33638ull, 45217756845074ull},
118  {11165857475563613320ull, 122823649010094ull, 90909ull, 82367704977874ull},
119  {5769661111434898342ull, 166479613883085ull, 34656ull, 143612702704582ull},
120  {595988210750343410ull, 96632566780240ull, 6167ull, 55171416603330ull},
121  {10823039041320808771ull, 194044969522035ull, 55775ull, 180866229306646ull},
122  {8191868136837774263ull, 21974809109129ull, 372784ull, 10897900229127ull},
123 
124  {10181553883373884575ull, 3338185436ull, 3050026452ull, 1892731503ull},
125  {1780389784881562605ull, 3324035064ull, 535611012ull, 329037837ull},
126  {11209516958321762174ull, 3248971057ull, 3450174458ull, 2679100068ull},
127  {553300379499061655ull, 1886172062ull, 293345655ull, 528971045ull},
128  {9905174405193618327ull, 219401111ull, 45146418630ull, 100520397ull},
129  {8240184070322019093ull, 2529206559ull, 3258011506ull, 49351239ull},
130  {558416785225208748ull, 588318741ull, 949173885ull, 211929963ull},
131  {18070010578094920982ull, 1478064986ull, 12225450673ull, 263485404ull},
132  {1762942926120765520ull, 2874579770ull, 613287181ull, 2417837150ull},
133  {18222958206762584970ull, 3886108634ull, 4689255994ull, 1442932774ull},
134  {6372532333203232188ull, 872018175ull, 7307797607ull, 677724963ull},
135  {11812660707898862825ull, 3632374734ull, 3252049023ull, 3024277943ull},
136  {1907291528073709144ull, 2685986883ull, 710089665ull, 2129844949ull},
137  {11884325264570431564ull, 2825710504ull, 4205783022ull, 1760168476ull},
138  {9500265779433438259ull, 515505699ull, 18429021828ull, 104040487ull},
139  {2640496290484060703ull, 2661299951ull, 992182895ull, 637522558ull},
140  {8314245057884472092ull, 1480724187ull, 5614985647ull, 713728103ull},
141  {8096890401121445834ull, 2938029060ull, 2755891870ull, 843703634ull},
142  {4445853448633802600ull, 1799659643ull, 2470385700ull, 1699497500ull},
143  {3731376883336662139ull, 1150569083ull, 3243070701ull, 782924956ull},
144  {1426363467586554810ull, 2933758551ull, 486189794ull, 2030126316ull},
145  {7946227974190787701ull, 4065181770ull, 1954704223ull, 1109172991ull},
146  {9269622039625861421ull, 3429366141ull, 2703013227ull, 276914414ull},
147  {13105234812485708591ull, 2360662048ull, 5551508240ull, 1158433071ull},
148  {13264580795231265125ull, 3140285014ull, 4224005380ull, 1361889805ull},
149  {13368532004903007054ull, 1424435189ull, 9385145851ull, 841256215ull},
150  {4711664378505588438ull, 2544984418ull, 1851352937ull, 1622052772ull},
151  {8484620585051396670ull, 10958842ull, 774226016311ull, 9724808ull},
152  {2093701182484354126ull, 1297611383ull, 1613504019ull, 913705849ull},
153  {98846011012594231ull, 774248727ull, 127666998ull, 331182685ull},
154  {8505512273053765473ull, 2554347139ull, 3329818466ull, 1037296699ull},
155  {17900303074650649604ull, 1271259881ull, 14080758263ull, 839502901ull},
156 
157  {2618787189332778102ull, 1221109647ull, 2144596266ull, 0},
158  {4661566478789449783ull, 3617798021ull, 1288509323ull, 0},
159  {1193973743395921536ull, 321518936ull, 3713540976ull, 0},
160  {1737911512256958624ull, 687157507ull, 2529131232ull, 0},
161  {181249124289945250ull, 1378418975ull, 131490590ull, 0},
162  {2146345082550878040ull, 733156664ull, 2927539485ull, 0},
163  {1622949150476392830ull, 1585888830ull, 1023368801ull, 0},
164  {663876118781380205ull, 296679587ull, 2237687215ull, 0},
165  {2777990016098405460ull, 815307460ull, 3407291301ull, 0},
166  {957942499325074748ull, 4028803567ull, 237773444ull, 0},
167  {4892243197152869016ull, 2252872938ull, 2171557532ull, 0},
168  {5054963385063225690ull, 1548826251ull, 3263738190ull, 0},
169  {6789579935278623548ull, 3898192909ull, 1741724972ull, 0},
170  {8115405604890247545ull, 3301069065ull, 2458417393ull, 0},
171  {4178534208521384192ull, 4099695136ull, 1019230472ull, 0},
172  {674548788821792312ull, 1522493188ull, 443055374ull, 0},
173  {16551611124853978205ull, 4017419995ull, 4119960359ull, 0},
174  {461883617422797520ull, 2727619280ull, 169335809ull, 0},
175  {8782840679992124220ull, 3015837441ull, 2912239420ull, 0},
176  {4298054348781624779ull, 1661399521ull, 2587008299ull, 0},
177  {2889455385802288061ull, 2231595817ull, 1294793333ull, 0},
178  {13313999585402914820ull, 3383189890ull, 3935339138ull, 0},
179  {13696572262444784196ull, 3568739493ull, 3837929972ull, 0},
180  {2301671643187023760ull, 3054807688ull, 753458770ull, 0},
181  {461135315050680928ull, 202385288ull, 2278502156ull, 0},
182  {300468280288186332ull, 147052332ull, 2043274501ull, 0},
183  {2266869802878007376ull, 592980332ull, 3822841468ull, 0},
184  {1279072648848501356ull, 1252368991ull, 1021322516ull, 0},
185  {6839727804122956563ull, 3297147757ull, 2074437759ull, 0},
186  {4572339959429543082ull, 3727623342ull, 1226609971ull, 0},
187  {12435319632655456416ull, 3368334101ull, 3691830816ull, 0},
188  {16449272219650625118ull, 3921581046ull, 4194551133ull, 0},
189 };
190 // clang-format on
191 
192 INSTANTIATE_TEST_SUITE_P(UDiv, UDivTest, testing::ValuesIn(kDivVectors));
193 
194 } // namespace
195 } // namespace math_unittest