mirror of https://gitlab.freedesktop.org/mesa/mesa
144 lines
2.5 KiB
C
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 */
|