| // 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 |