Revert "nasmlib/file.c: Windows _chsize_s() *returns* errno"
[nasm.git] / iflag.h
blob84e7d75c20e992bc0251e5a4b3f1db4aa83f1add
1 #ifndef NASM_IFLAG_H
2 #define NASM_IFLAG_H
5 #include <string.h>
7 #include "compiler.h"
9 int ilog2_32(uint32_t v);
11 #include "iflaggen.h"
13 #define IF_GENBIT(bit) (UINT32_C(1) << (bit))
15 static inline unsigned int iflag_test(const iflag_t *f, unsigned int bit)
17 unsigned int index = bit / 32;
18 return f->field[index] & (UINT32_C(1) << (bit - (index * 32)));
21 static inline void iflag_set(iflag_t *f, unsigned int bit)
23 unsigned int index = bit / 32;
24 f->field[index] |= (UINT32_C(1) << (bit - (index * 32)));
27 static inline void iflag_clear(iflag_t *f, unsigned int bit)
29 unsigned int index = bit / 32;
30 f->field[index] &= ~(UINT32_C(1) << (bit - (index * 32)));
33 static inline void iflag_clear_all(iflag_t *f)
35 memset(f, 0, sizeof(*f));
38 static inline void iflag_set_all(iflag_t *f)
40 memset(f, 0xff, sizeof(*f));
43 static inline int iflag_cmp(const iflag_t *a, const iflag_t *b)
45 int i;
47 for (i = sizeof(a->field) / sizeof(a->field[0]) - 1; i >= 0; i--) {
48 if (a->field[i] == b->field[i])
49 continue;
51 return (a->field[i] > b->field[i]) ? 1 : -1;
54 return 0;
57 static inline int iflag_cmp_cpu(const iflag_t *a, const iflag_t *b)
59 if (a->field[3] < b->field[3])
60 return -1;
61 else if (a->field[3] > b->field[3])
62 return 1;
63 return 0;
66 static inline unsigned int iflag_ffs(const iflag_t *a)
68 unsigned int i;
70 for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) {
71 if (a->field[i])
72 return ilog2_32(a->field[i]) + (i * 32);
75 return 0;
78 #define IF_GEN_HELPER(name, op) \
79 static inline iflag_t iflag_##name(const iflag_t *a, const iflag_t *b) \
80 { \
81 unsigned int i; \
82 iflag_t res; \
84 for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) \
85 res.field[i] = a->field[i] op b->field[i]; \
87 return res; \
90 IF_GEN_HELPER(xor, ^)
93 /* Use this helper to test instruction template flags */
94 #define itemp_has(itemp, bit) iflag_test(&insns_flags[(itemp)->iflag_idx], bit)
97 /* Maximum processor level at moment */
98 #define IF_PLEVEL IF_IA64
99 /* Some helpers which are to work with predefined masks */
100 #define IF_SMASK \
101 (IF_GENBIT(IF_SB) |\
102 IF_GENBIT(IF_SW) |\
103 IF_GENBIT(IF_SD) |\
104 IF_GENBIT(IF_SQ) |\
105 IF_GENBIT(IF_SO) |\
106 IF_GENBIT(IF_SY) |\
107 IF_GENBIT(IF_SZ) |\
108 IF_GENBIT(IF_SIZE))
109 #define IF_ARMASK \
110 (IF_GENBIT(IF_AR0) |\
111 IF_GENBIT(IF_AR1) |\
112 IF_GENBIT(IF_AR2) |\
113 IF_GENBIT(IF_AR3) |\
114 IF_GENBIT(IF_AR4))
116 #define _itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK)
117 #define _itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK)
118 #define _itemp_arg(idx) ((_itemp_armask(idx) >> IF_AR0) - 1)
120 #define itemp_smask(itemp) _itemp_smask((itemp)->iflag_idx)
121 #define itemp_arg(itemp) _itemp_arg((itemp)->iflag_idx)
122 #define itemp_armask(itemp) _itemp_armask((itemp)->iflag_idx)
124 static inline int iflag_cmp_cpu_level(const iflag_t *a, const iflag_t *b)
126 iflag_t v1 = *a;
127 iflag_t v2 = *b;
129 iflag_clear(&v1, IF_CYRIX);
130 iflag_clear(&v1, IF_AMD);
132 iflag_clear(&v2, IF_CYRIX);
133 iflag_clear(&v2, IF_AMD);
135 if (v1.field[3] < v2.field[3])
136 return -1;
137 else if (v1.field[3] > v2.field[3])
138 return 1;
140 return 0;
143 static inline iflag_t _iflag_pfmask(const iflag_t *a)
145 iflag_t r;
147 iflag_clear_all(&r);
149 if (iflag_test(a, IF_CYRIX))
150 iflag_set(&r, IF_CYRIX);
151 if (iflag_test(a, IF_AMD))
152 iflag_set(&r, IF_AMD);
154 return r;
157 #define iflag_pfmask(itemp) _iflag_pfmask(&insns_flags[(itemp)->iflag_idx])
159 #endif /* NASM_IFLAG_H */