|  | // Copyright lowRISC contributors. | 
|  | // Licensed under the Apache License, Version 2.0, see LICENSE for details. | 
|  | // SPDX-License-Identifier: Apache-2.0 | 
|  |  | 
|  | #include "sw/device/lib/base/math.h" | 
|  |  | 
|  | #include <ostream> | 
|  | #include <stdint.h> | 
|  | #include <tuple> | 
|  |  | 
|  | #include "gmock/gmock.h" | 
|  | #include "gtest/gtest.h" | 
|  |  | 
|  | namespace math_unittest { | 
|  | namespace { | 
|  |  | 
|  | struct DivVector { | 
|  | uint64_t a, b, q, r; | 
|  |  | 
|  | friend void operator<<(std::ostream &out, const DivVector &v) { | 
|  | out << "{" << v.a << ", " << v.b << ", " << v.q << ", " << v.r << "}"; | 
|  | } | 
|  | }; | 
|  |  | 
|  | class UDivTest : public testing::TestWithParam<DivVector> {}; | 
|  |  | 
|  | TEST_P(UDivTest, UDiv64) { | 
|  | uint64_t rem; | 
|  | EXPECT_EQ(udiv64_slow(GetParam().a, GetParam().b, &rem), GetParam().q); | 
|  | EXPECT_EQ(rem, GetParam().r); | 
|  | } | 
|  |  | 
|  | // Simple python snippet for generating vectors: | 
|  | // | 
|  | // import random | 
|  | // # Full division. | 
|  | // for _ in range(0, 32): | 
|  | //   a, b = random.getrandbits(64), random.getrandbits(64) | 
|  | //   print(f"{{{a}ull, {b}ull, {a//b}ull, {a%b}ull}},") | 
|  | // | 
|  | // # Div by u48 | 
|  | // for _ in range(0, 32): | 
|  | //   a, b = random.getrandbits(64), random.getrandbits(48) | 
|  | //   print(f"{{{a}ull, {b}ull, {a//b}ull, {a%b}ull}},") | 
|  | // | 
|  | // # Div by u32 | 
|  | // for _ in range(0, 32): | 
|  | //   a, b = random.getrandbits(64), random.getrandbits(32) | 
|  | //   print(f"{{{a}ull, {b}ull, {a//b}ull, {a%b}ull}},") | 
|  | // | 
|  | // # Product of u32s. | 
|  | // for _ in range(0, 32): | 
|  | //   b, q = random.getrandbits(32), random.getrandbits(32) | 
|  | //   print(f"{{{b*q}ull, {b}ull, {q}ull, 0}},") | 
|  | // | 
|  | // clang-format off | 
|  | constexpr DivVector kDivVectors[] = { | 
|  | {16547064864992412266ull, 15362666177494521751ull, 1ull, 1184398687497890515ull}, | 
|  | {15117832593278048550ull, 9509133006104311255ull, 1ull, 5608699587173737295ull}, | 
|  | {7700533544865790561ull, 16200507889521424080ull, 0ull, 7700533544865790561ull}, | 
|  | {15751090594484430019ull, 4841336985583654393ull, 3ull, 1227079637733466840ull}, | 
|  | {1569256689953856309ull, 15136191600906927243ull, 0ull, 1569256689953856309ull}, | 
|  | {11646355910642376023ull, 16233286557913565679ull, 0ull, 11646355910642376023ull}, | 
|  | {11467848857967805770ull, 15343115856225830326ull, 0ull, 11467848857967805770ull}, | 
|  | {7082930862597735748ull, 13044336721903538272ull, 0ull, 7082930862597735748ull}, | 
|  | {7440142190527596899ull, 10232543569022431683ull, 0ull, 7440142190527596899ull}, | 
|  | {6162319322407126380ull, 14510700894994718373ull, 0ull, 6162319322407126380ull}, | 
|  | {11421574008009519807ull, 3446073093067775855ull, 3ull, 1083354728806192242ull}, | 
|  | {13590081538404264686ull, 5283212502034404741ull, 2ull, 3023656534335455204ull}, | 
|  | {14232045355477928062ull, 539825197847590283ull, 26ull, 196590211440580704ull}, | 
|  | {12580731027378952841ull, 16693509274214597629ull, 0ull, 12580731027378952841ull}, | 
|  | {17671460965360506731ull, 11247238544147177319ull, 1ull, 6424222421213329412ull}, | 
|  | {9664461898672776233ull, 9295631859719160580ull, 1ull, 368830038953615653ull}, | 
|  | {11015643691959628501ull, 11371567295203483667ull, 0ull, 11015643691959628501ull}, | 
|  | {8617136599055270914ull, 14553847862380133083ull, 0ull, 8617136599055270914ull}, | 
|  | {17480416258340506086ull, 5930856364822663088ull, 2ull, 5618703528695179910ull}, | 
|  | {14301781298682298274ull, 13686260976492283484ull, 1ull, 615520322190014790ull}, | 
|  | {12717390489997499836ull, 12396402423110714892ull, 1ull, 320988066886784944ull}, | 
|  | {9478693902079965650ull, 13922637938150164298ull, 0ull, 9478693902079965650ull}, | 
|  | {2218148139848502258ull, 16575500956377955560ull, 0ull, 2218148139848502258ull}, | 
|  | {6715234203200040462ull, 7716128746410333163ull, 0ull, 6715234203200040462ull}, | 
|  | {10620210067079001965ull, 2822959022621217088ull, 3ull, 2151332999215350701ull}, | 
|  | {14376175987504050882ull, 9698201778735636497ull, 1ull, 4677974208768414385ull}, | 
|  | {17907411000270102820ull, 4932086816672498435ull, 3ull, 3111150550252607515ull}, | 
|  | {2009523729344663635ull, 9177774962461691174ull, 0ull, 2009523729344663635ull}, | 
|  | {7794275604495320889ull, 17051579788896461924ull, 0ull, 7794275604495320889ull}, | 
|  | {1908688452509192803ull, 9477953155444810610ull, 0ull, 1908688452509192803ull}, | 
|  | {9865370653618144874ull, 2917100723726114133ull, 3ull, 1114068482439802475ull}, | 
|  | {14868378943466010358ull, 6893180186547617045ull, 2ull, 1082018570370776268ull}, | 
|  |  | 
|  | {15589205337902788058ull, 113947965797624ull, 136809ull, 98085095646242ull}, | 
|  | {154443034356190258ull, 212455867024500ull, 726ull, 200074896403258ull}, | 
|  | {14373381053726099454ull, 73780700389417ull, 194812ull, 15249462994850ull}, | 
|  | {12817128855238948341ull, 281345225603344ull, 45556ull, 165757653009077ull}, | 
|  | {6160912619711259892ull, 28980646173628ull, 212587ull, 3991598204256ull}, | 
|  | {15269508067345212820ull, 45485386217644ull, 335701ull, 18428695904376ull}, | 
|  | {7988213334521806465ull, 80165028719043ull, 99647ull, 8717755328644ull}, | 
|  | {17258038462583660946ull, 251077212750735ull, 68735ull, 246244161890721ull}, | 
|  | {1207754801805538860ull, 263416992465745ull, 4584ull, 251308342563780ull}, | 
|  | {8563707882399609092ull, 165228409036947ull, 51829ull, 84670423683029ull}, | 
|  | {746182492253572191ull, 195673554129159ull, 3813ull, 79230359088924ull}, | 
|  | {8496739951993591715ull, 228035340749822ull, 37260ull, 143155655223995ull}, | 
|  | {17292881127045336612ull, 248845483734607ull, 69492ull, 110771360026968ull}, | 
|  | {12005998103417887352ull, 252693626264731ull, 47512ull, 18532327988080ull}, | 
|  | {13076033720356300636ull, 69662783623236ull, 187704ull, 50583140410492ull}, | 
|  | {13331639988452463714ull, 232041084383213ull, 57453ull, 183567383727225ull}, | 
|  | {11740525896774895061ull, 142808904399401ull, 82211ull, 63057195739450ull}, | 
|  | {17175044619609759631ull, 158020044602567ull, 108689ull, 3991801354968ull}, | 
|  | {11951085009197228545ull, 189341158583116ull, 63119ull, 60420589529741ull}, | 
|  | {17835462114951798285ull, 162607057461277ull, 109684ull, 69624369091817ull}, | 
|  | {6950646436399140076ull, 14758119174077ull, 470971ull, 290864921309ull}, | 
|  | {6726003104404773273ull, 270548366585651ull, 24860ull, 170711085489413ull}, | 
|  | {6399411722239535722ull, 266575135796259ull, 24006ull, 9012314542168ull}, | 
|  | {13670372028797309326ull, 245433997117396ull, 55698ull, 189257352586918ull}, | 
|  | {4411737990115626057ull, 46185890582147ull, 95521ull, 15535818362470ull}, | 
|  | {6658768816131697888ull, 128030080935156ull, 52009ull, 52336775169484ull}, | 
|  | {7484953986642594286ull, 222513489770074ull, 33638ull, 45217756845074ull}, | 
|  | {11165857475563613320ull, 122823649010094ull, 90909ull, 82367704977874ull}, | 
|  | {5769661111434898342ull, 166479613883085ull, 34656ull, 143612702704582ull}, | 
|  | {595988210750343410ull, 96632566780240ull, 6167ull, 55171416603330ull}, | 
|  | {10823039041320808771ull, 194044969522035ull, 55775ull, 180866229306646ull}, | 
|  | {8191868136837774263ull, 21974809109129ull, 372784ull, 10897900229127ull}, | 
|  |  | 
|  | {10181553883373884575ull, 3338185436ull, 3050026452ull, 1892731503ull}, | 
|  | {1780389784881562605ull, 3324035064ull, 535611012ull, 329037837ull}, | 
|  | {11209516958321762174ull, 3248971057ull, 3450174458ull, 2679100068ull}, | 
|  | {553300379499061655ull, 1886172062ull, 293345655ull, 528971045ull}, | 
|  | {9905174405193618327ull, 219401111ull, 45146418630ull, 100520397ull}, | 
|  | {8240184070322019093ull, 2529206559ull, 3258011506ull, 49351239ull}, | 
|  | {558416785225208748ull, 588318741ull, 949173885ull, 211929963ull}, | 
|  | {18070010578094920982ull, 1478064986ull, 12225450673ull, 263485404ull}, | 
|  | {1762942926120765520ull, 2874579770ull, 613287181ull, 2417837150ull}, | 
|  | {18222958206762584970ull, 3886108634ull, 4689255994ull, 1442932774ull}, | 
|  | {6372532333203232188ull, 872018175ull, 7307797607ull, 677724963ull}, | 
|  | {11812660707898862825ull, 3632374734ull, 3252049023ull, 3024277943ull}, | 
|  | {1907291528073709144ull, 2685986883ull, 710089665ull, 2129844949ull}, | 
|  | {11884325264570431564ull, 2825710504ull, 4205783022ull, 1760168476ull}, | 
|  | {9500265779433438259ull, 515505699ull, 18429021828ull, 104040487ull}, | 
|  | {2640496290484060703ull, 2661299951ull, 992182895ull, 637522558ull}, | 
|  | {8314245057884472092ull, 1480724187ull, 5614985647ull, 713728103ull}, | 
|  | {8096890401121445834ull, 2938029060ull, 2755891870ull, 843703634ull}, | 
|  | {4445853448633802600ull, 1799659643ull, 2470385700ull, 1699497500ull}, | 
|  | {3731376883336662139ull, 1150569083ull, 3243070701ull, 782924956ull}, | 
|  | {1426363467586554810ull, 2933758551ull, 486189794ull, 2030126316ull}, | 
|  | {7946227974190787701ull, 4065181770ull, 1954704223ull, 1109172991ull}, | 
|  | {9269622039625861421ull, 3429366141ull, 2703013227ull, 276914414ull}, | 
|  | {13105234812485708591ull, 2360662048ull, 5551508240ull, 1158433071ull}, | 
|  | {13264580795231265125ull, 3140285014ull, 4224005380ull, 1361889805ull}, | 
|  | {13368532004903007054ull, 1424435189ull, 9385145851ull, 841256215ull}, | 
|  | {4711664378505588438ull, 2544984418ull, 1851352937ull, 1622052772ull}, | 
|  | {8484620585051396670ull, 10958842ull, 774226016311ull, 9724808ull}, | 
|  | {2093701182484354126ull, 1297611383ull, 1613504019ull, 913705849ull}, | 
|  | {98846011012594231ull, 774248727ull, 127666998ull, 331182685ull}, | 
|  | {8505512273053765473ull, 2554347139ull, 3329818466ull, 1037296699ull}, | 
|  | {17900303074650649604ull, 1271259881ull, 14080758263ull, 839502901ull}, | 
|  |  | 
|  | {2618787189332778102ull, 1221109647ull, 2144596266ull, 0}, | 
|  | {4661566478789449783ull, 3617798021ull, 1288509323ull, 0}, | 
|  | {1193973743395921536ull, 321518936ull, 3713540976ull, 0}, | 
|  | {1737911512256958624ull, 687157507ull, 2529131232ull, 0}, | 
|  | {181249124289945250ull, 1378418975ull, 131490590ull, 0}, | 
|  | {2146345082550878040ull, 733156664ull, 2927539485ull, 0}, | 
|  | {1622949150476392830ull, 1585888830ull, 1023368801ull, 0}, | 
|  | {663876118781380205ull, 296679587ull, 2237687215ull, 0}, | 
|  | {2777990016098405460ull, 815307460ull, 3407291301ull, 0}, | 
|  | {957942499325074748ull, 4028803567ull, 237773444ull, 0}, | 
|  | {4892243197152869016ull, 2252872938ull, 2171557532ull, 0}, | 
|  | {5054963385063225690ull, 1548826251ull, 3263738190ull, 0}, | 
|  | {6789579935278623548ull, 3898192909ull, 1741724972ull, 0}, | 
|  | {8115405604890247545ull, 3301069065ull, 2458417393ull, 0}, | 
|  | {4178534208521384192ull, 4099695136ull, 1019230472ull, 0}, | 
|  | {674548788821792312ull, 1522493188ull, 443055374ull, 0}, | 
|  | {16551611124853978205ull, 4017419995ull, 4119960359ull, 0}, | 
|  | {461883617422797520ull, 2727619280ull, 169335809ull, 0}, | 
|  | {8782840679992124220ull, 3015837441ull, 2912239420ull, 0}, | 
|  | {4298054348781624779ull, 1661399521ull, 2587008299ull, 0}, | 
|  | {2889455385802288061ull, 2231595817ull, 1294793333ull, 0}, | 
|  | {13313999585402914820ull, 3383189890ull, 3935339138ull, 0}, | 
|  | {13696572262444784196ull, 3568739493ull, 3837929972ull, 0}, | 
|  | {2301671643187023760ull, 3054807688ull, 753458770ull, 0}, | 
|  | {461135315050680928ull, 202385288ull, 2278502156ull, 0}, | 
|  | {300468280288186332ull, 147052332ull, 2043274501ull, 0}, | 
|  | {2266869802878007376ull, 592980332ull, 3822841468ull, 0}, | 
|  | {1279072648848501356ull, 1252368991ull, 1021322516ull, 0}, | 
|  | {6839727804122956563ull, 3297147757ull, 2074437759ull, 0}, | 
|  | {4572339959429543082ull, 3727623342ull, 1226609971ull, 0}, | 
|  | {12435319632655456416ull, 3368334101ull, 3691830816ull, 0}, | 
|  | {16449272219650625118ull, 3921581046ull, 4194551133ull, 0}, | 
|  | }; | 
|  | // clang-format on | 
|  |  | 
|  | INSTANTIATE_TEST_SUITE_P(UDiv, UDivTest, testing::ValuesIn(kDivVectors)); | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace math_unittest |