10 int ilog2_32(uint32_t v
);
13 * Instruction template flags. These specify which processor
14 * targets the instruction is eligible for, whether it is
15 * privileged or undocumented, and also specify extra error
16 * checking on the matching of the instruction.
18 * IF_SM stands for Size Match: any operand whose size is not
19 * explicitly specified by the template is `really' intended to be
20 * the same size as the first size-specified operand.
21 * Non-specification is tolerated in the input instruction, but
22 * _wrong_ specification is not.
24 * IF_SM2 invokes Size Match on only the first _two_ operands, for
25 * three-operand instructions such as SHLD: it implies that the
26 * first two operands must match in size, but that the third is
27 * required to be _unspecified_.
29 * IF_SB invokes Size Byte: operands with unspecified size in the
30 * template are really bytes, and so no non-byte specification in
31 * the input instruction will be tolerated. IF_SW similarly invokes
32 * Size Word, and IF_SD invokes Size Doubleword.
34 * (The default state if neither IF_SM nor IF_SM2 is specified is
35 * that any operand with unspecified size in the template is
36 * required to have unspecified size in the instruction too...)
38 * iflag_t is defined to store these flags.
42 #define IF_GENBIT(bit) (UINT32_C(1) << (bit))
44 static inline unsigned int iflag_test(iflag_t
*f
,unsigned int bit
)
46 unsigned int index
= bit
/ 32;
47 return f
->field
[index
] & (UINT32_C(1) << (bit
- (index
* 32)));
50 static inline void iflag_set(iflag_t
*f
, unsigned int bit
)
52 unsigned int index
= bit
/ 32;
53 f
->field
[index
] |= (UINT32_C(1) << (bit
- (index
* 32)));
56 static inline void iflag_clear(iflag_t
*f
, unsigned int bit
)
58 unsigned int index
= bit
/ 32;
59 f
->field
[index
] &= ~(UINT32_C(1) << (bit
- (index
* 32)));
62 static inline void iflag_clear_all(iflag_t
*f
)
64 memset(f
, 0, sizeof(*f
));
67 static inline void iflag_set_all(iflag_t
*f
)
69 memset(f
, 0xff, sizeof(*f
));
72 static inline int iflag_cmp(iflag_t
*a
, iflag_t
*b
)
76 for (i
= 0; i
< sizeof(a
->field
) / sizeof(a
->field
[0]); i
++) {
77 if (a
->field
[i
] < b
->field
[i
])
79 else if (a
->field
[i
] > b
->field
[i
])
86 static inline int iflag_cmp_cpu(iflag_t
*a
, iflag_t
*b
)
88 if (a
->field
[3] < b
->field
[3])
90 else if (a
->field
[3] > b
->field
[3])
95 static inline unsigned int iflag_ffs(iflag_t
*a
)
99 for (i
= 0; i
< sizeof(a
->field
) / sizeof(a
->field
[0]); i
++) {
101 return ilog2_32(a
->field
[i
]) + (i
* 32);
107 #define IF_GEN_HELPER(name, op) \
108 static inline iflag_t iflag_##name(iflag_t *a, iflag_t *b) \
113 for (i = 0; i < sizeof(a->field) / sizeof(a->field[0]); i++) \
114 res.field[i] = a->field[i] op b->field[i]; \
119 IF_GEN_HELPER(xor, ^)
122 /* Use this helper to test instruction template flags */
123 #define itemp_has(itemp, bit) iflag_test(&insns_flags[(itemp)->iflag_idx], bit)
126 /* Maximum processor level at moment */
127 #define IF_PLEVEL IF_IA64
128 /* Some helpers which are to work with predefined masks */
139 (IF_GENBIT(IF_AR0) |\
145 #define __itemp_smask(idx) (insns_flags[(idx)].field[0] & IF_SMASK)
146 #define __itemp_armask(idx) (insns_flags[(idx)].field[0] & IF_ARMASK)
147 #define __itemp_arg(idx) ((__itemp_armask(idx) >> IF_AR0) - 1)
149 #define itemp_smask(itemp) __itemp_smask((itemp)->iflag_idx)
150 #define itemp_arg(itemp) __itemp_arg((itemp)->iflag_idx)
151 #define itemp_armask(itemp) __itemp_armask((itemp)->iflag_idx)
153 static inline int iflag_cmp_cpu_level(iflag_t
*a
, iflag_t
*b
)
158 iflag_clear(&v1
, IF_CYRIX
);
159 iflag_clear(&v1
, IF_AMD
);
161 iflag_clear(&v2
, IF_CYRIX
);
162 iflag_clear(&v2
, IF_AMD
);
164 if (v1
.field
[3] < v2
.field
[3])
166 else if (v1
.field
[3] > v2
.field
[3])
172 static inline iflag_t
__iflag_pfmask(iflag_t
*a
)
174 iflag_t r
= (iflag_t
) {
175 .field
[1] = a
->field
[1],
176 .field
[2] = a
->field
[2],
179 if (iflag_test(a
, IF_CYRIX
))
180 iflag_set(&r
, IF_CYRIX
);
181 if (iflag_test(a
, IF_AMD
))
182 iflag_set(&r
, IF_AMD
);
187 #define iflag_pfmask(itemp) __iflag_pfmask(&insns_flags[(itemp)->iflag_idx])
189 #endif /* NASM_IFLAG_H__ */