diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 772191d965c..1c0799f912e 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -1757,113 +1757,37 @@ INSTR0(FENCE) INSTR0(META_TEX_PREFETCH); /* ************************************************************************* */ -/* split this out or find some helper to use.. like main/bitset.h.. */ - -#include -#include "util/bitset.h" - -#define MAX_REG 256 - -typedef BITSET_DECLARE(regmaskstate_t, 2 * MAX_REG); - -typedef struct { - bool mergedregs; - regmaskstate_t mask; -} regmask_t; - -static inline bool -__regmask_get(regmask_t *regmask, struct ir3_register *reg, unsigned n) -{ - if (regmask->mergedregs) { - /* a6xx+ case, with merged register file, we track things in terms - * of half-precision registers, with a full precisions register - * using two half-precision slots: - */ - if (reg->flags & IR3_REG_HALF) { - return BITSET_TEST(regmask->mask, n); - } else { - n *= 2; - return BITSET_TEST(regmask->mask, n) || - BITSET_TEST(regmask->mask, n+1); - } - } else { - /* pre a6xx case, with separate register file for half and full - * precision: - */ - if (reg->flags & IR3_REG_HALF) - n += MAX_REG; - return BITSET_TEST(regmask->mask, n); - } -} - -static inline void -__regmask_set(regmask_t *regmask, struct ir3_register *reg, unsigned n) -{ - if (regmask->mergedregs) { - /* a6xx+ case, with merged register file, we track things in terms - * of half-precision registers, with a full precisions register - * using two half-precision slots: - */ - if (reg->flags & IR3_REG_HALF) { - BITSET_SET(regmask->mask, n); - } else { - n *= 2; - BITSET_SET(regmask->mask, n); - BITSET_SET(regmask->mask, n+1); - } - } else { - /* pre a6xx case, with separate register file for half and full - * precision: - */ - if (reg->flags & IR3_REG_HALF) - n += MAX_REG; - BITSET_SET(regmask->mask, n); - } -} - -static inline void regmask_init(regmask_t *regmask, bool mergedregs) -{ - memset(®mask->mask, 0, sizeof(regmask->mask)); - regmask->mergedregs = mergedregs; -} +#include "regmask.h" static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg) { + bool half = reg->flags & IR3_REG_HALF; if (reg->flags & IR3_REG_RELATIV) { for (unsigned i = 0; i < reg->size; i++) - __regmask_set(regmask, reg, reg->array.offset + i); + __regmask_set(regmask, half, reg->array.offset + i); } else { for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++) if (mask & 1) - __regmask_set(regmask, reg, n); + __regmask_set(regmask, half, n); } } -static inline void regmask_or(regmask_t *dst, regmask_t *a, regmask_t *b) -{ - assert(dst->mergedregs == a->mergedregs); - assert(dst->mergedregs == b->mergedregs); - - for (unsigned i = 0; i < ARRAY_SIZE(dst->mask); i++) - dst->mask[i] = a->mask[i] | b->mask[i]; -} - static inline bool regmask_get(regmask_t *regmask, struct ir3_register *reg) { + bool half = reg->flags & IR3_REG_HALF; if (reg->flags & IR3_REG_RELATIV) { for (unsigned i = 0; i < reg->size; i++) - if (__regmask_get(regmask, reg, reg->array.offset + i)) + if (__regmask_get(regmask, half, reg->array.offset + i)) return true; } else { for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++) if (mask & 1) - if (__regmask_get(regmask, reg, n)) + if (__regmask_get(regmask, half, n)) return true; } return false; } - /* ************************************************************************* */ #endif /* IR3_H_ */ diff --git a/src/freedreno/ir3/meson.build b/src/freedreno/ir3/meson.build index 833543d9fda..192a8608103 100644 --- a/src/freedreno/ir3/meson.build +++ b/src/freedreno/ir3/meson.build @@ -103,6 +103,7 @@ libfreedreno_ir3_files = files( 'ir3_shader.c', 'ir3_shader.h', 'ir3_validate.c', + 'regmask.h', ) libfreedreno_ir3 = static_library( diff --git a/src/freedreno/ir3/regmask.h b/src/freedreno/ir3/regmask.h new file mode 100644 index 00000000000..6eade8daf01 --- /dev/null +++ b/src/freedreno/ir3/regmask.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013 Rob Clark + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef REGMASK_H_ +#define REGMASK_H_ + +#include +#include "util/bitset.h" + +#define MAX_REG 256 + +typedef BITSET_DECLARE(regmaskstate_t, 2 * MAX_REG); + +typedef struct { + bool mergedregs; + regmaskstate_t mask; +} regmask_t; + +static inline bool +__regmask_get(regmask_t *regmask, bool half, unsigned n) +{ + if (regmask->mergedregs) { + /* a6xx+ case, with merged register file, we track things in terms + * of half-precision registers, with a full precisions register + * using two half-precision slots: + */ + if (half) { + return BITSET_TEST(regmask->mask, n); + } else { + n *= 2; + return BITSET_TEST(regmask->mask, n) || + BITSET_TEST(regmask->mask, n+1); + } + } else { + /* pre a6xx case, with separate register file for half and full + * precision: + */ + if (half) + n += MAX_REG; + return BITSET_TEST(regmask->mask, n); + } +} + +static inline void +__regmask_set(regmask_t *regmask, bool half, unsigned n) +{ + if (regmask->mergedregs) { + /* a6xx+ case, with merged register file, we track things in terms + * of half-precision registers, with a full precisions register + * using two half-precision slots: + */ + if (half) { + BITSET_SET(regmask->mask, n); + } else { + n *= 2; + BITSET_SET(regmask->mask, n); + BITSET_SET(regmask->mask, n+1); + } + } else { + /* pre a6xx case, with separate register file for half and full + * precision: + */ + if (half) + n += MAX_REG; + BITSET_SET(regmask->mask, n); + } +} + +static inline void +regmask_init(regmask_t *regmask, bool mergedregs) +{ + memset(®mask->mask, 0, sizeof(regmask->mask)); + regmask->mergedregs = mergedregs; +} + +static inline void +regmask_or(regmask_t *dst, regmask_t *a, regmask_t *b) +{ + assert(dst->mergedregs == a->mergedregs); + assert(dst->mergedregs == b->mergedregs); + + for (unsigned i = 0; i < ARRAY_SIZE(dst->mask); i++) + dst->mask[i] = a->mask[i] | b->mask[i]; +} + +#endif /* REGMASK_H_ */