mesa/src/nouveau/mme/mme_value.h

144 lines
2.5 KiB
C

/*
* Copyright © 2022 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#ifndef MME_VALUE_H
#define MME_VALUE_H
#include <stdbool.h>
#include <stdint.h>
#include "util/bitscan.h"
#include "util/macros.h"
#ifdef __cplusplus
extern "C" {
#endif
enum mme_value_type {
/* This must be zero, making a zero-initizlied mme_value a ZERO */
MME_VALUE_TYPE_ZERO = 0,
MME_VALUE_TYPE_IMM,
MME_VALUE_TYPE_REG,
};
struct mme_value {
enum mme_value_type type;
union {
uint32_t imm;
uint32_t reg;
};
};
struct mme_value64 {
struct mme_value lo;
struct mme_value hi;
};
static inline struct mme_value
mme_zero()
{
struct mme_value val = {
.type = MME_VALUE_TYPE_ZERO,
};
return val;
}
static inline struct mme_value
mme_imm(uint32_t imm)
{
struct mme_value val = {
.type = MME_VALUE_TYPE_IMM,
.imm = imm,
};
return val;
}
static inline bool
mme_is_zero(struct mme_value x)
{
switch (x.type) {
case MME_VALUE_TYPE_ZERO: return true;
case MME_VALUE_TYPE_IMM: return x.imm == 0;
case MME_VALUE_TYPE_REG: return false;
default: unreachable("Invalid MME value type");
}
}
static inline struct mme_value64
mme_value64(struct mme_value lo, struct mme_value hi)
{
struct mme_value64 val = { lo, hi };
return val;
}
static inline struct mme_value64
mme_imm64(uint64_t imm)
{
struct mme_value64 val = {
mme_imm((uint32_t)imm),
mme_imm((uint32_t)(imm >> 32)),
};
return val;
}
struct mme_reg_alloc {
uint32_t exists;
uint32_t alloc;
};
static inline void
mme_reg_alloc_init(struct mme_reg_alloc *a, uint32_t exists)
{
a->alloc = 0;
a->exists = exists;
}
static inline struct mme_value
mme_reg_alloc_alloc(struct mme_reg_alloc *a)
{
uint8_t reg = ffs(~a->alloc & a->exists) - 1;
assert(reg < 32);
assert(a->exists & (1u << reg));
a->alloc |= (1u << reg);
struct mme_value val = {
.type = MME_VALUE_TYPE_REG,
.reg = reg,
};
return val;
}
static inline void
mme_reg_alloc_realloc(struct mme_reg_alloc *a, struct mme_value val)
{
assert(val.type == MME_VALUE_TYPE_REG);
assert(val.reg < 32);
assert(a->exists & (1u << val.reg));
assert(!(a->alloc & (1u << val.reg)));
a->alloc |= (1u << val.reg);
}
static inline void
mme_reg_alloc_free(struct mme_reg_alloc *a, struct mme_value val)
{
assert(val.type == MME_VALUE_TYPE_REG);
assert(val.reg < 32);
assert(a->exists & (1u << val.reg));
assert(a->alloc & (1u << val.reg));
a->alloc &= ~(1u << val.reg);
}
#ifdef __cplusplus
}
#endif
#endif /* MME_VALUE_H */