11 #define IF_GENBIT(bit) (UINT32_C(1) << (bit))
13 static inline bool iflag_test(const iflag_t
*f
, unsigned int bit
)
15 return !!(f
->field
[bit
>> 5] & IF_GENBIT(bit
& 31));
18 static inline void iflag_set(iflag_t
*f
, unsigned int bit
)
20 f
->field
[bit
>> 5] |= IF_GENBIT(bit
& 31);
23 static inline void iflag_clear(iflag_t
*f
, unsigned int bit
)
25 f
->field
[bit
>> 5] &= ~IF_GENBIT(bit
& 31);
28 static inline void iflag_clear_all(iflag_t
*f
)
30 memset(f
, 0, sizeof(*f
));
33 static inline void iflag_set_all(iflag_t
*f
)
35 memset(f
, ~0, sizeof(*f
));
38 #define iflag_for_each_field(v) for ((v) = 0; (v) < IF_FIELD_COUNT; (v)++)
40 static inline int iflag_cmp(const iflag_t
*a
, const iflag_t
*b
)
44 /* This is intentionally a reverse loop! */
45 for (i
= IF_FIELD_COUNT
-1; i
>= 0; i
--) {
46 if (a
->field
[i
] == b
->field
[i
])
49 return (int)(a
->field
[i
] - b
->field
[i
]);
55 #define IF_GEN_HELPER(name, op) \
56 static inline iflag_t iflag_##name(const iflag_t *a, const iflag_t *b) \
61 iflag_for_each_field(i) \
62 res.field[i] = a->field[i] op b->field[i]; \
69 /* Some helpers which are to work with predefined masks */
86 #define _itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK)
87 #define _itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK)
88 #define _itemp_arg(idx) ((_itemp_armask(idx) >> IF_AR0) - 1)
90 #define itemp_smask(itemp) _itemp_smask((itemp)->iflag_idx)
91 #define itemp_arg(itemp) _itemp_arg((itemp)->iflag_idx)
92 #define itemp_armask(itemp) _itemp_armask((itemp)->iflag_idx)
95 * IF_8086 is the first CPU level flag and IF_PLEVEL the last
98 #error "IF_8086 must be on a uint32_t boundary"
100 #define IF_PLEVEL IF_IA64
101 #define IF_CPU_FIELD (IF_8086 >> 5)
102 #define IF_CPU_LEVEL_MASK ((IF_GENBIT(IF_PLEVEL & 31) << 1) - 1)
105 * IF_PRIV is the firstr instruction filtering flag
108 #error "IF_PRIV must be on a uint32_t boundary"
110 #define IF_FEATURE_FIELD (IF_PRIV >> 5)
112 static inline int iflag_cmp_cpu(const iflag_t
*a
, const iflag_t
*b
)
114 return (int)(a
->field
[IF_CPU_FIELD
] - b
->field
[IF_CPU_FIELD
]);
117 static inline uint32_t _iflag_cpu_level(const iflag_t
*a
)
119 return a
->field
[IF_CPU_FIELD
] & IF_CPU_LEVEL_MASK
;
122 static inline int iflag_cmp_cpu_level(const iflag_t
*a
, const iflag_t
*b
)
124 uint32_t aa
= _iflag_cpu_level(a
);
125 uint32_t bb
= _iflag_cpu_level(b
);
127 return (int)(aa
- bb
);
130 /* Returns true if the CPU level is at least a certain value */
131 static inline bool iflag_cpu_level_ok(const iflag_t
*a
, unsigned int bit
)
133 return _iflag_cpu_level(a
) >= IF_GENBIT(bit
& 31);
136 static inline void iflag_set_all_features(iflag_t
*a
)
140 for (i
= IF_FEATURE_FIELD
; i
< IF_CPU_FIELD
; i
++)
141 a
->field
[i
] = ~UINT32_C(0);
144 static inline void iflag_set_cpu(iflag_t
*a
, unsigned int cpu
)
146 a
->field
[0] = 0; /* Not applicable to the CPU type */
147 iflag_set_all_features(a
); /* All feature masking bits set for now */
148 a
->field
[IF_CPU_FIELD
] &= ~IF_CPU_LEVEL_MASK
;
152 static inline void iflag_set_default_cpu(iflag_t
*a
)
154 iflag_set_cpu(a
, IF_PLEVEL
);
157 static inline iflag_t
_iflag_pfmask(const iflag_t
*a
)
163 if (iflag_test(a
, IF_CYRIX
))
164 iflag_set(&r
, IF_CYRIX
);
165 if (iflag_test(a
, IF_AMD
))
166 iflag_set(&r
, IF_AMD
);
171 #define iflag_pfmask(itemp) _iflag_pfmask(&insns_flags[(itemp)->iflag_idx])
173 #endif /* NASM_IFLAG_H */