diff options
author | polwex <polwex@sortug.com> | 2025-10-05 21:56:51 +0700 |
---|---|---|
committer | polwex <polwex@sortug.com> | 2025-10-05 21:56:51 +0700 |
commit | fcedfddf00b3f994e4f4e40332ac7fc192c63244 (patch) | |
tree | 51d38e62c7bdfcc5f9a5e9435fe820c93cfc9a3d /vere/ext/nasm/include/iflag.h |
claude is gud
Diffstat (limited to 'vere/ext/nasm/include/iflag.h')
-rw-r--r-- | vere/ext/nasm/include/iflag.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/vere/ext/nasm/include/iflag.h b/vere/ext/nasm/include/iflag.h new file mode 100644 index 0000000..31a0a98 --- /dev/null +++ b/vere/ext/nasm/include/iflag.h @@ -0,0 +1,134 @@ +#ifndef NASM_IFLAG_H +#define NASM_IFLAG_H + +#include "compiler.h" +#include "ilog2.h" + + +#include "iflaggen.h" + +#define IF_GENBIT(bit) (UINT32_C(1) << ((bit) & 31)) + +static inline int ifcomp(uint32_t a, uint32_t b) +{ + return (a > b) - (a < b); +} + +static inline bool iflag_test(const iflag_t *f, unsigned int bit) +{ + return !!(f->field[bit >> 5] & IF_GENBIT(bit)); +} + +static inline void iflag_set(iflag_t *f, unsigned int bit) +{ + f->field[bit >> 5] |= IF_GENBIT(bit); +} + +static inline void iflag_clear(iflag_t *f, unsigned int bit) +{ + f->field[bit >> 5] &= ~IF_GENBIT(bit); +} + +static inline void iflag_clear_all(iflag_t *f) +{ + memset(f, 0, sizeof(*f)); +} + +static inline void iflag_set_all(iflag_t *f) +{ + memset(f, ~0, sizeof(*f)); +} + +#define iflag_for_each_field(v) for ((v) = 0; (v) < IF_FIELD_COUNT; (v)++) + +static inline int iflag_cmp(const iflag_t *a, const iflag_t *b) +{ + int i; + + /* This is intentionally a reverse loop! */ + for (i = IF_FIELD_COUNT-1; i >= 0; i--) { + if (a->field[i] == b->field[i]) + continue; + + return ifcomp(a->field[i], b->field[i]); + } + + return 0; +} + +#define IF_GEN_HELPER(name, op) \ + static inline iflag_t iflag_##name(const iflag_t *a, const iflag_t *b) \ + { \ + unsigned int i; \ + iflag_t res; \ + \ + iflag_for_each_field(i) \ + res.field[i] = a->field[i] op b->field[i]; \ + \ + return res; \ + } + +IF_GEN_HELPER(xor, ^) + +/* Some helpers which are to work with predefined masks */ +#define IF_SMASK (IFM_SB|IFM_SW|IFM_SD|IFM_SQ|IFM_SO|IFM_SY|IFM_SZ|IFM_SIZE|IFM_ANYSIZE) +#define IF_ARMASK (IFM_AR0|IFM_AR1|IFM_AR2|IFM_AR3|IFM_AR4) + +#define _itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK) +#define _itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK) +#define _itemp_arg(idx) ((_itemp_armask(idx) >> IF_AR0) - 1) + +#define itemp_smask(itemp) _itemp_smask((itemp)->iflag_idx) +#define itemp_arg(itemp) _itemp_arg((itemp)->iflag_idx) +#define itemp_armask(itemp) _itemp_armask((itemp)->iflag_idx) + +/* + * IF_ANY is the highest CPU level by definition + */ +#define IF_CPU_LEVEL_MASK ((IFM_ANY << 1) - 1) + +static inline int iflag_cmp_cpu(const iflag_t *a, const iflag_t *b) +{ + return ifcomp(a->field[IF_CPU_FIELD], b->field[IF_CPU_FIELD]); +} + +static inline uint32_t _iflag_cpu_level(const iflag_t *a) +{ + return a->field[IF_CPU_FIELD] & IF_CPU_LEVEL_MASK; +} + +static inline int iflag_cmp_cpu_level(const iflag_t *a, const iflag_t *b) +{ + return ifcomp(_iflag_cpu_level(a), _iflag_cpu_level(b)); +} + +/* Returns true if the CPU level is at least a certain value */ +static inline bool iflag_cpu_level_ok(const iflag_t *a, unsigned int bit) +{ + return _iflag_cpu_level(a) >= IF_GENBIT(bit); +} + +static inline void iflag_set_all_features(iflag_t *a) +{ + uint32_t *p = &a->field[IF_FEATURE_FIELD]; + + memset(p, -1, IF_FEATURE_NFIELDS * sizeof(uint32_t)); +} + +static inline iflag_t _iflag_pfmask(const iflag_t *a) +{ + iflag_t r; + + iflag_clear_all(&r); + + if (iflag_test(a, IF_CYRIX)) + iflag_set(&r, IF_CYRIX); + if (iflag_test(a, IF_AMD)) + iflag_set(&r, IF_AMD); + + return r; +} + +#define iflag_pfmask(itemp) _iflag_pfmask(&insns_flags[(itemp)->iflag_idx]) + +#endif /* NASM_IFLAG_H */ |