"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/amd/addrlib/src/core/coord.cpp" (16 Sep 2020, 12904 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "coord.cpp" see the Fossies "Dox" file reference documentation.

    1 
    2 /*
    3  * Copyright © 2007-2019 Advanced Micro Devices, Inc.
    4  * All Rights Reserved.
    5  *
    6  * Permission is hereby granted, free of charge, to any person obtaining
    7  * a copy of this software and associated documentation files (the
    8  * "Software"), to deal in the Software without restriction, including
    9  * without limitation the rights to use, copy, modify, merge, publish,
   10  * distribute, sub license, and/or sell copies of the Software, and to
   11  * permit persons to whom the Software is furnished to do so, subject to
   12  * the following conditions:
   13  *
   14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   16  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   17  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
   18  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
   21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
   22  *
   23  * The above copyright notice and this permission notice (including the
   24  * next paragraph) shall be included in all copies or substantial portions
   25  * of the Software.
   26  */
   27 
   28 // Coordinate class implementation
   29 #include "addrcommon.h"
   30 #include "coord.h"
   31 
   32 namespace Addr
   33 {
   34 namespace V2
   35 {
   36 
   37 Coordinate::Coordinate()
   38 {
   39     dim = DIM_X;
   40     ord = 0;
   41 }
   42 
   43 Coordinate::Coordinate(enum Dim dim, INT_32 n)
   44 {
   45     set(dim, n);
   46 }
   47 
   48 VOID Coordinate::set(enum Dim d, INT_32 n)
   49 {
   50     dim = d;
   51     ord = static_cast<INT_8>(n);
   52 }
   53 
   54 UINT_32 Coordinate::ison(const UINT_32 *coords) const
   55 {
   56     UINT_32 bit = static_cast<UINT_32>(1ull << static_cast<UINT_32>(ord));
   57 
   58     return (coords[dim] & bit) ? 1 : 0;
   59 }
   60 
   61 enum Dim Coordinate::getdim()
   62 {
   63     return dim;
   64 }
   65 
   66 INT_8 Coordinate::getord()
   67 {
   68     return ord;
   69 }
   70 
   71 BOOL_32 Coordinate::operator==(const Coordinate& b)
   72 {
   73     return (dim == b.dim) && (ord == b.ord);
   74 }
   75 
   76 BOOL_32 Coordinate::operator<(const Coordinate& b)
   77 {
   78     BOOL_32 ret;
   79 
   80     if (dim == b.dim)
   81     {
   82         ret = ord < b.ord;
   83     }
   84     else
   85     {
   86         if (dim == DIM_S || b.dim == DIM_M)
   87         {
   88             ret = TRUE;
   89         }
   90         else if (b.dim == DIM_S || dim == DIM_M)
   91         {
   92             ret = FALSE;
   93         }
   94         else if (ord == b.ord)
   95         {
   96             ret = dim < b.dim;
   97         }
   98         else
   99         {
  100             ret = ord < b.ord;
  101         }
  102     }
  103 
  104     return ret;
  105 }
  106 
  107 BOOL_32 Coordinate::operator>(const Coordinate& b)
  108 {
  109     BOOL_32 lt = *this < b;
  110     BOOL_32 eq = *this == b;
  111     return !lt && !eq;
  112 }
  113 
  114 BOOL_32 Coordinate::operator<=(const Coordinate& b)
  115 {
  116     return (*this < b) || (*this == b);
  117 }
  118 
  119 BOOL_32 Coordinate::operator>=(const Coordinate& b)
  120 {
  121     return !(*this < b);
  122 }
  123 
  124 BOOL_32 Coordinate::operator!=(const Coordinate& b)
  125 {
  126     return !(*this == b);
  127 }
  128 
  129 Coordinate& Coordinate::operator++(INT_32)
  130 {
  131     ord++;
  132     return *this;
  133 }
  134 
  135 // CoordTerm
  136 
  137 CoordTerm::CoordTerm()
  138 {
  139     num_coords = 0;
  140 }
  141 
  142 VOID CoordTerm::Clear()
  143 {
  144     num_coords = 0;
  145 }
  146 
  147 VOID CoordTerm::add(Coordinate& co)
  148 {
  149     // This function adds a coordinate INT_32o the list
  150     // It will prevent the same coordinate from appearing,
  151     // and will keep the list ordered from smallest to largest
  152     UINT_32 i;
  153 
  154     for (i = 0; i < num_coords; i++)
  155     {
  156         if (m_coord[i] == co)
  157         {
  158             break;
  159         }
  160         if (m_coord[i] > co)
  161         {
  162             for (UINT_32 j = num_coords; j > i; j--)
  163             {
  164                 m_coord[j] = m_coord[j - 1];
  165             }
  166             m_coord[i] = co;
  167             num_coords++;
  168             break;
  169         }
  170     }
  171 
  172     if (i == num_coords)
  173     {
  174         m_coord[num_coords] = co;
  175         num_coords++;
  176     }
  177 }
  178 
  179 VOID CoordTerm::add(CoordTerm& cl)
  180 {
  181     for (UINT_32 i = 0; i < cl.num_coords; i++)
  182     {
  183         add(cl.m_coord[i]);
  184     }
  185 }
  186 
  187 BOOL_32 CoordTerm::remove(Coordinate& co)
  188 {
  189     BOOL_32 remove = FALSE;
  190     for (UINT_32 i = 0; i < num_coords; i++)
  191     {
  192         if (m_coord[i] == co)
  193         {
  194             remove = TRUE;
  195             num_coords--;
  196         }
  197 
  198         if (remove)
  199         {
  200             m_coord[i] = m_coord[i + 1];
  201         }
  202     }
  203     return remove;
  204 }
  205 
  206 BOOL_32 CoordTerm::Exists(Coordinate& co)
  207 {
  208     BOOL_32 exists = FALSE;
  209     for (UINT_32 i = 0; i < num_coords; i++)
  210     {
  211         if (m_coord[i] == co)
  212         {
  213             exists = TRUE;
  214             break;
  215         }
  216     }
  217     return exists;
  218 }
  219 
  220 VOID CoordTerm::copyto(CoordTerm& cl)
  221 {
  222     cl.num_coords = num_coords;
  223     for (UINT_32 i = 0; i < num_coords; i++)
  224     {
  225         cl.m_coord[i] = m_coord[i];
  226     }
  227 }
  228 
  229 UINT_32 CoordTerm::getsize()
  230 {
  231     return num_coords;
  232 }
  233 
  234 UINT_32 CoordTerm::getxor(const UINT_32 *coords) const
  235 {
  236     UINT_32 out = 0;
  237     for (UINT_32 i = 0; i < num_coords; i++)
  238     {
  239         out = out ^ m_coord[i].ison(coords);
  240     }
  241     return out;
  242 }
  243 
  244 VOID CoordTerm::getsmallest(Coordinate& co)
  245 {
  246     co = m_coord[0];
  247 }
  248 
  249 UINT_32 CoordTerm::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
  250 {
  251     for (UINT_32 i = start;  i < num_coords;)
  252     {
  253         if (((f == '<' && m_coord[i] < co) ||
  254              (f == '>' && m_coord[i] > co) ||
  255              (f == '=' && m_coord[i] == co)) &&
  256             (axis == NUM_DIMS || axis == m_coord[i].getdim()))
  257         {
  258             for (UINT_32 j = i; j < num_coords - 1; j++)
  259             {
  260                 m_coord[j] = m_coord[j + 1];
  261             }
  262             num_coords--;
  263         }
  264         else
  265         {
  266             i++;
  267         }
  268     }
  269     return num_coords;
  270 }
  271 
  272 Coordinate& CoordTerm::operator[](UINT_32 i)
  273 {
  274     return m_coord[i];
  275 }
  276 
  277 BOOL_32 CoordTerm::operator==(const CoordTerm& b)
  278 {
  279     BOOL_32 ret = TRUE;
  280 
  281     if (num_coords != b.num_coords)
  282     {
  283         ret = FALSE;
  284     }
  285     else
  286     {
  287         for (UINT_32 i = 0; i < num_coords; i++)
  288         {
  289             // Note: the lists will always be in order, so we can compare the two lists at time
  290             if (m_coord[i] != b.m_coord[i])
  291             {
  292                 ret = FALSE;
  293                 break;
  294             }
  295         }
  296     }
  297     return ret;
  298 }
  299 
  300 BOOL_32 CoordTerm::operator!=(const CoordTerm& b)
  301 {
  302     return !(*this == b);
  303 }
  304 
  305 BOOL_32 CoordTerm::exceedRange(const UINT_32 *ranges)
  306 {
  307     BOOL_32 exceed = FALSE;
  308     for (UINT_32 i = 0; (i < num_coords) && (exceed == FALSE); i++)
  309     {
  310         exceed = ((1u << m_coord[i].getord()) <= ranges[m_coord[i].getdim()]);
  311     }
  312 
  313     return exceed;
  314 }
  315 
  316 // coordeq
  317 CoordEq::CoordEq()
  318 {
  319     m_numBits = 0;
  320 }
  321 
  322 VOID CoordEq::remove(Coordinate& co)
  323 {
  324     for (UINT_32 i = 0; i < m_numBits; i++)
  325     {
  326         m_eq[i].remove(co);
  327     }
  328 }
  329 
  330 BOOL_32 CoordEq::Exists(Coordinate& co)
  331 {
  332     BOOL_32 exists = FALSE;
  333 
  334     for (UINT_32 i = 0; i < m_numBits; i++)
  335     {
  336         if (m_eq[i].Exists(co))
  337         {
  338             exists = TRUE;
  339         }
  340     }
  341     return exists;
  342 }
  343 
  344 VOID CoordEq::resize(UINT_32 n)
  345 {
  346     if (n > m_numBits)
  347     {
  348         for (UINT_32 i = m_numBits; i < n; i++)
  349         {
  350             m_eq[i].Clear();
  351         }
  352     }
  353     m_numBits = n;
  354 }
  355 
  356 UINT_32 CoordEq::getsize()
  357 {
  358     return m_numBits;
  359 }
  360 
  361 UINT_64 CoordEq::solve(const UINT_32 *coords) const
  362 {
  363     UINT_64 out = 0;
  364     for (UINT_32 i = 0; i < m_numBits; i++)
  365     {
  366         out |= static_cast<UINT_64>(m_eq[i].getxor(coords)) << i;
  367     }
  368     return out;
  369 }
  370 
  371 VOID CoordEq::solveAddr(
  372     UINT_64 addr, UINT_32 sliceInM,
  373     UINT_32 *coords) const
  374 {
  375     UINT_32 BitsValid[NUM_DIMS] = {0};
  376 
  377     CoordEq temp = *this;
  378 
  379     memset(coords, 0, NUM_DIMS * sizeof(coords[0]));
  380 
  381     UINT_32 bitsLeft = 0;
  382 
  383     for (UINT_32 i = 0; i < temp.m_numBits; i++)
  384     {
  385         UINT_32 termSize = temp.m_eq[i].getsize();
  386 
  387         if (termSize == 1)
  388         {
  389             INT_8 bit = (addr >> i) & 1;
  390             enum Dim dim = temp.m_eq[i][0].getdim();
  391             INT_8 ord = temp.m_eq[i][0].getord();
  392 
  393             ADDR_ASSERT((ord < 32) || (bit == 0));
  394 
  395             BitsValid[dim] |= 1u << ord;
  396             coords[dim] |= bit << ord;
  397 
  398             temp.m_eq[i].Clear();
  399         }
  400         else if (termSize > 1)
  401         {
  402             bitsLeft++;
  403         }
  404     }
  405 
  406     if (bitsLeft > 0)
  407     {
  408         if (sliceInM != 0)
  409         {
  410             coords[DIM_Z] = coords[DIM_M] / sliceInM;
  411             BitsValid[DIM_Z] = 0xffffffff;
  412         }
  413 
  414         do
  415         {
  416             bitsLeft = 0;
  417 
  418             for (UINT_32 i = 0; i < temp.m_numBits; i++)
  419             {
  420                 UINT_32 termSize = temp.m_eq[i].getsize();
  421 
  422                 if (termSize == 1)
  423                 {
  424                     INT_8 bit = (addr >> i) & 1;
  425                     enum Dim dim = temp.m_eq[i][0].getdim();
  426                     INT_8 ord = temp.m_eq[i][0].getord();
  427 
  428                     ADDR_ASSERT((ord < 32) || (bit == 0));
  429                     ADDR_ASSERT(dim < DIM_S);
  430 
  431                     BitsValid[dim] |= 1u << ord;
  432                     coords[dim] |= bit << ord;
  433 
  434                     temp.m_eq[i].Clear();
  435                 }
  436                 else if (termSize > 1)
  437                 {
  438                     CoordTerm tmpTerm = temp.m_eq[i];
  439 
  440                     for (UINT_32 j = 0; j < termSize; j++)
  441                     {
  442                         enum Dim dim = temp.m_eq[i][j].getdim();
  443                         INT_8 ord = temp.m_eq[i][j].getord();
  444 
  445                         ADDR_ASSERT(dim < DIM_S);
  446 
  447                         if (BitsValid[dim] & (1u << ord))
  448                         {
  449                             UINT_32 v = (((coords[dim] >> ord) & 1) << i);
  450                             addr ^= static_cast<UINT_64>(v);
  451                             tmpTerm.remove(temp.m_eq[i][j]);
  452                         }
  453                     }
  454 
  455                     temp.m_eq[i] = tmpTerm;
  456 
  457                     bitsLeft++;
  458                 }
  459             }
  460         } while (bitsLeft > 0);
  461     }
  462 }
  463 
  464 VOID CoordEq::copy(CoordEq& o, UINT_32 start, UINT_32 num)
  465 {
  466     o.m_numBits = (num == 0xFFFFFFFF) ? m_numBits : num;
  467     for (UINT_32 i = 0; i < o.m_numBits; i++)
  468     {
  469         m_eq[start + i].copyto(o.m_eq[i]);
  470     }
  471 }
  472 
  473 VOID CoordEq::reverse(UINT_32 start, UINT_32 num)
  474 {
  475     UINT_32 n = (num == 0xFFFFFFFF) ? m_numBits : num;
  476 
  477     for (UINT_32 i = 0; i < n / 2; i++)
  478     {
  479         CoordTerm temp;
  480         m_eq[start + i].copyto(temp);
  481         m_eq[start + n - 1 - i].copyto(m_eq[start + i]);
  482         temp.copyto(m_eq[start + n - 1 - i]);
  483     }
  484 }
  485 
  486 VOID CoordEq::xorin(CoordEq& x, UINT_32 start)
  487 {
  488     UINT_32 n = ((m_numBits - start) < x.m_numBits) ? (m_numBits - start) : x.m_numBits;
  489     for (UINT_32 i = 0; i < n; i++)
  490     {
  491         m_eq[start + i].add(x.m_eq[i]);
  492     }
  493 }
  494 
  495 UINT_32 CoordEq::Filter(INT_8 f, Coordinate& co, UINT_32 start, enum Dim axis)
  496 {
  497     for (UINT_32 i = start; i < m_numBits;)
  498     {
  499         UINT_32 m = m_eq[i].Filter(f, co, 0, axis);
  500         if (m == 0)
  501         {
  502             for (UINT_32 j = i; j < m_numBits - 1; j++)
  503             {
  504                 m_eq[j] = m_eq[j + 1];
  505             }
  506             m_numBits--;
  507         }
  508         else
  509         {
  510             i++;
  511         }
  512     }
  513     return m_numBits;
  514 }
  515 
  516 VOID CoordEq::shift(INT_32 amount, INT_32 start)
  517 {
  518     if (amount != 0)
  519     {
  520         INT_32 numBits = static_cast<INT_32>(m_numBits);
  521         amount = -amount;
  522         INT_32 inc = (amount < 0) ? -1 : 1;
  523         INT_32 i = (amount < 0) ? numBits - 1 : start;
  524         INT_32 end = (amount < 0) ? start - 1 : numBits;
  525         for (; (inc > 0) ? i < end : i > end; i += inc)
  526         {
  527             if ((i + amount < start) || (i + amount >= numBits))
  528             {
  529                 m_eq[i].Clear();
  530             }
  531             else
  532             {
  533                 m_eq[i + amount].copyto(m_eq[i]);
  534             }
  535         }
  536     }
  537 }
  538 
  539 CoordTerm& CoordEq::operator[](UINT_32 i)
  540 {
  541     return m_eq[i];
  542 }
  543 
  544 VOID CoordEq::mort2d(Coordinate& c0, Coordinate& c1, UINT_32 start, UINT_32 end)
  545 {
  546     if (end == 0)
  547     {
  548         ADDR_ASSERT(m_numBits > 0);
  549         end = m_numBits - 1;
  550     }
  551     for (UINT_32 i = start; i <= end; i++)
  552     {
  553         UINT_32 select = (i - start) % 2;
  554         Coordinate& c = (select == 0) ? c0 : c1;
  555         m_eq[i].add(c);
  556         c++;
  557     }
  558 }
  559 
  560 VOID CoordEq::mort3d(Coordinate& c0, Coordinate& c1, Coordinate& c2, UINT_32 start, UINT_32 end)
  561 {
  562     if (end == 0)
  563     {
  564         ADDR_ASSERT(m_numBits > 0);
  565         end = m_numBits - 1;
  566     }
  567     for (UINT_32 i = start; i <= end; i++)
  568     {
  569         UINT_32 select = (i - start) % 3;
  570         Coordinate& c = (select == 0) ? c0 : ((select == 1) ? c1 : c2);
  571         m_eq[i].add(c);
  572         c++;
  573     }
  574 }
  575 
  576 BOOL_32 CoordEq::operator==(const CoordEq& b)
  577 {
  578     BOOL_32 ret = TRUE;
  579 
  580     if (m_numBits != b.m_numBits)
  581     {
  582         ret = FALSE;
  583     }
  584     else
  585     {
  586         for (UINT_32 i = 0; i < m_numBits; i++)
  587         {
  588             if (m_eq[i] != b.m_eq[i])
  589             {
  590                 ret = FALSE;
  591                 break;
  592             }
  593         }
  594     }
  595     return ret;
  596 }
  597 
  598 BOOL_32 CoordEq::operator!=(const CoordEq& b)
  599 {
  600     return !(*this == b);
  601 }
  602 
  603 } // V2
  604 } // Addr