~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/amd/addrlib/src/core/coord.cpp

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

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