xref: /aosp_15_r20/external/mesa3d/src/nouveau/mme/mme_value.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2022 Collabora Ltd.
3  * SPDX-License-Identifier: MIT
4  */
5 #ifndef MME_VALUE_H
6 #define MME_VALUE_H
7 
8 #include <stdbool.h>
9 #include <stdint.h>
10 
11 #include "util/bitscan.h"
12 #include "util/macros.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 enum mme_value_type {
19    /* This must be zero, making a zero-initizlied mme_value a ZERO */
20    MME_VALUE_TYPE_ZERO = 0,
21    MME_VALUE_TYPE_IMM,
22    MME_VALUE_TYPE_REG,
23 };
24 
25 struct mme_value {
26    enum mme_value_type type;
27 
28    union {
29       uint32_t imm;
30       uint32_t reg;
31    };
32 };
33 
34 struct mme_value64 {
35    struct mme_value lo;
36    struct mme_value hi;
37 };
38 
39 static inline struct mme_value
mme_zero()40 mme_zero()
41 {
42    struct mme_value val = {
43       .type = MME_VALUE_TYPE_ZERO,
44    };
45    return val;
46 }
47 
48 static inline struct mme_value
mme_imm(uint32_t imm)49 mme_imm(uint32_t imm)
50 {
51    struct mme_value val = {
52       .type = MME_VALUE_TYPE_IMM,
53       .imm = imm,
54    };
55    return val;
56 }
57 
58 static inline bool
mme_is_zero(struct mme_value x)59 mme_is_zero(struct mme_value x)
60 {
61    switch (x.type) {
62    case MME_VALUE_TYPE_ZERO:  return true;
63    case MME_VALUE_TYPE_IMM:   return x.imm == 0;
64    case MME_VALUE_TYPE_REG:   return false;
65    default: unreachable("Invalid MME value type");
66    }
67 }
68 
69 static inline struct mme_value64
mme_value64(struct mme_value lo,struct mme_value hi)70 mme_value64(struct mme_value lo, struct mme_value hi)
71 {
72    struct mme_value64 val = { lo, hi };
73    return val;
74 }
75 
76 static inline struct mme_value64
mme_imm64(uint64_t imm)77 mme_imm64(uint64_t imm)
78 {
79    struct mme_value64 val = {
80       mme_imm((uint32_t)imm),
81       mme_imm((uint32_t)(imm >> 32)),
82    };
83    return val;
84 }
85 
86 struct mme_reg_alloc {
87    uint32_t exists;
88    uint32_t alloc;
89 };
90 
91 static inline void
mme_reg_alloc_init(struct mme_reg_alloc * a,uint32_t exists)92 mme_reg_alloc_init(struct mme_reg_alloc *a, uint32_t exists)
93 {
94    a->alloc = 0;
95    a->exists = exists;
96 }
97 
98 static inline struct mme_value
mme_reg_alloc_alloc(struct mme_reg_alloc * a)99 mme_reg_alloc_alloc(struct mme_reg_alloc *a)
100 {
101    uint8_t reg = ffs(~a->alloc & a->exists) - 1;
102    assert(reg < 32);
103    assert(a->exists & (1u << reg));
104 
105    a->alloc |= (1u << reg);
106 
107    struct mme_value val = {
108       .type = MME_VALUE_TYPE_REG,
109       .reg = reg,
110    };
111 
112    return val;
113 }
114 
115 static inline void
mme_reg_alloc_realloc(struct mme_reg_alloc * a,struct mme_value val)116 mme_reg_alloc_realloc(struct mme_reg_alloc *a, struct mme_value val)
117 {
118    assert(val.type == MME_VALUE_TYPE_REG);
119 
120    assert(val.reg < 32);
121    assert(a->exists & (1u << val.reg));
122    assert(!(a->alloc & (1u << val.reg)));
123 
124    a->alloc |= (1u << val.reg);
125 }
126 
127 static inline void
mme_reg_alloc_free(struct mme_reg_alloc * a,struct mme_value val)128 mme_reg_alloc_free(struct mme_reg_alloc *a, struct mme_value val)
129 {
130    assert(val.type == MME_VALUE_TYPE_REG);
131 
132    assert(val.reg < 32);
133    assert(a->exists & (1u << val.reg));
134    assert(a->alloc & (1u << val.reg));
135 
136    a->alloc &= ~(1u << val.reg);
137 }
138 
139 #ifdef __cplusplus
140 }
141 #endif
142 
143 #endif /* MME_VALUE_H */
144