10 #define IF_GENBIT(bit) (UINT32_C(1) << ((bit) & 31))
12 static inline int ifcomp(uint32_t a
, uint32_t b
)
14 return (a
> b
) - (a
< b
);
17 static inline bool iflag_test(const iflag_t
*f
, unsigned int bit
)
19 return !!(f
->field
[bit
>> 5] & IF_GENBIT(bit
));
22 static inline void iflag_set(iflag_t
*f
, unsigned int bit
)
24 f
->field
[bit
>> 5] |= IF_GENBIT(bit
);
27 static inline void iflag_clear(iflag_t
*f
, unsigned int bit
)
29 f
->field
[bit
>> 5] &= ~IF_GENBIT(bit
);
32 static inline void iflag_clear_all(iflag_t
*f
)
34 memset(f
, 0, sizeof(*f
));
37 static inline void iflag_set_all(iflag_t
*f
)
39 memset(f
, ~0, sizeof(*f
));
42 #define iflag_for_each_field(v) for ((v) = 0; (v) < IF_FIELD_COUNT; (v)++)
44 static inline int iflag_cmp(const iflag_t
*a
, const iflag_t
*b
)
48 /* This is intentionally a reverse loop! */
49 for (i
= IF_FIELD_COUNT
-1; i
>= 0; i
--) {
50 if (a
->field
[i
] == b
->field
[i
])
53 return ifcomp(a
->field
[i
], b
->field
[i
]);
59 #define IF_GEN_HELPER(name, op) \
60 static inline iflag_t iflag_##name(const iflag_t *a, const iflag_t *b) \
65 iflag_for_each_field(i) \
66 res.field[i] = a->field[i] op b->field[i]; \
73 /* Some helpers which are to work with predefined masks */
74 #define IF_SMASK (IFM_SB|IFM_SW|IFM_SD|IFM_SQ|IFM_SO|IFM_SY|IFM_SZ|IFM_SIZE|IFM_ANYSIZE)
75 #define IF_ARMASK (IFM_AR0|IFM_AR1|IFM_AR2|IFM_AR3|IFM_AR4)
77 #define _itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK)
78 #define _itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK)
79 #define _itemp_arg(idx) ((_itemp_armask(idx) >> IF_AR0) - 1)
81 #define itemp_smask(itemp) _itemp_smask((itemp)->iflag_idx)
82 #define itemp_arg(itemp) _itemp_arg((itemp)->iflag_idx)
83 #define itemp_armask(itemp) _itemp_armask((itemp)->iflag_idx)
86 * IF_ANY is the highest CPU level by definition
88 #define IF_PLEVEL IF_ANY /* Default CPU level */
89 #define IF_CPU_LEVEL_MASK ((IFM_ANY << 1) - 1)
91 static inline int iflag_cmp_cpu(const iflag_t
*a
, const iflag_t
*b
)
93 return ifcomp(a
->field
[IF_CPU_FIELD
], b
->field
[IF_CPU_FIELD
]);
96 static inline uint32_t _iflag_cpu_level(const iflag_t
*a
)
98 return a
->field
[IF_CPU_FIELD
] & IF_CPU_LEVEL_MASK
;
101 static inline int iflag_cmp_cpu_level(const iflag_t
*a
, const iflag_t
*b
)
103 return ifcomp(_iflag_cpu_level(a
), _iflag_cpu_level(b
));
106 /* Returns true if the CPU level is at least a certain value */
107 static inline bool iflag_cpu_level_ok(const iflag_t
*a
, unsigned int bit
)
109 return _iflag_cpu_level(a
) >= IF_GENBIT(bit
);
112 static inline void iflag_set_all_features(iflag_t
*a
)
114 uint32_t *p
= &a
->field
[IF_FEATURE_FIELD
];
116 memset(p
, -1, IF_FEATURE_NFIELDS
* sizeof(uint32_t));
119 static inline void iflag_set_cpu(iflag_t
*a
, unsigned int cpu
)
121 a
->field
[0] = 0; /* Not applicable to the CPU type */
122 iflag_set_all_features(a
); /* All feature masking bits set for now */
123 a
->field
[IF_CPU_FIELD
] &= ~IF_CPU_LEVEL_MASK
;
127 static inline void iflag_set_default_cpu(iflag_t
*a
)
129 iflag_set_cpu(a
, IF_PLEVEL
);
132 static inline iflag_t
_iflag_pfmask(const iflag_t
*a
)
138 if (iflag_test(a
, IF_CYRIX
))
139 iflag_set(&r
, IF_CYRIX
);
140 if (iflag_test(a
, IF_AMD
))
141 iflag_set(&r
, IF_AMD
);
146 #define iflag_pfmask(itemp) _iflag_pfmask(&insns_flags[(itemp)->iflag_idx])
148 #endif /* NASM_IFLAG_H */