]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/i386-gen.c
x86: rename CheckRegSize to CheckOperandSize
[thirdparty/binutils-gdb.git] / opcodes / i386-gen.c
CommitLineData
a2c58332 1/* Copyright (C) 2007-2022 Free Software Foundation, Inc.
40b8e679 2
9b201bb5 3 This file is part of the GNU opcodes library.
40b8e679 4
9b201bb5 5 This library is free software; you can redistribute it and/or modify
40b8e679 6 it under the terms of the GNU General Public License as published by
9b201bb5
NC
7 the Free Software Foundation; either version 3, or (at your option)
8 any later version.
40b8e679 9
9b201bb5
NC
10 It is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
13 License for more details.
40b8e679
L
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
9b201bb5
NC
17 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
18 MA 02110-1301, USA. */
40b8e679 19
40fb9820 20#include "sysdep.h"
40b8e679 21#include <stdio.h>
40b8e679
L
22#include <errno.h>
23#include "getopt.h"
24#include "libiberty.h"
c587b3f9 25#include "hashtab.h"
40b8e679
L
26#include "safe-ctype.h"
27
28#include "i386-opc.h"
29
30#include <libintl.h>
31#define _(String) gettext (String)
32
1d942ae9
JB
33/* Build-time checks are preferrable over runtime ones. Use this construct
34 in preference where possible. */
35#define static_assert(e) ((void)sizeof (struct { int _:1 - 2 * !(e); }))
36
40b8e679
L
37static const char *program_name = NULL;
38static int debug = 0;
39
40fb9820
L
40typedef struct initializer
41{
42 const char *name;
43 const char *init;
44} initializer;
45
8acd5377 46static initializer cpu_flag_init[] =
40fb9820
L
47{
48 { "CPU_UNKNOWN_FLAGS",
4fdeb2a3 49 "~IAMCU" },
40fb9820 50 { "CPU_GENERIC32_FLAGS",
4fdeb2a3 51 "186|286|386" },
29c048b6 52 { "CPU_GENERIC64_FLAGS",
4fdeb2a3 53 "CPU_PENTIUMPRO_FLAGS|Clflush|SYSCALL|CPU_MMX_FLAGS|CPU_SSE2_FLAGS|LM" },
40fb9820
L
54 { "CPU_NONE_FLAGS",
55 "0" },
56 { "CPU_I186_FLAGS",
4fdeb2a3 57 "186" },
40fb9820 58 { "CPU_I286_FLAGS",
4fdeb2a3 59 "CPU_I186_FLAGS|286" },
40fb9820 60 { "CPU_I386_FLAGS",
4fdeb2a3 61 "CPU_I286_FLAGS|386" },
40fb9820 62 { "CPU_I486_FLAGS",
4fdeb2a3 63 "CPU_I386_FLAGS|486" },
40fb9820 64 { "CPU_I586_FLAGS",
4fdeb2a3 65 "CPU_I486_FLAGS|387|586" },
40fb9820 66 { "CPU_I686_FLAGS",
4fdeb2a3 67 "CPU_I586_FLAGS|686|687|CMOV|FXSR" },
22109423 68 { "CPU_PENTIUMPRO_FLAGS",
4fdeb2a3 69 "CPU_I686_FLAGS|Nop" },
40fb9820 70 { "CPU_P2_FLAGS",
1848e567 71 "CPU_PENTIUMPRO_FLAGS|CPU_MMX_FLAGS" },
40fb9820 72 { "CPU_P3_FLAGS",
1848e567 73 "CPU_P2_FLAGS|CPU_SSE_FLAGS" },
40fb9820 74 { "CPU_P4_FLAGS",
4fdeb2a3 75 "CPU_P3_FLAGS|Clflush|CPU_SSE2_FLAGS" },
40fb9820 76 { "CPU_NOCONA_FLAGS",
4fdeb2a3 77 "CPU_GENERIC64_FLAGS|FISTTP|CPU_SSE3_FLAGS|CX16" },
40fb9820 78 { "CPU_CORE_FLAGS",
4fdeb2a3 79 "CPU_P4_FLAGS|FISTTP|CPU_SSE3_FLAGS|CX16" },
40fb9820 80 { "CPU_CORE2_FLAGS",
1848e567 81 "CPU_NOCONA_FLAGS|CPU_SSSE3_FLAGS" },
bd5295b2 82 { "CPU_COREI7_FLAGS",
4fdeb2a3 83 "CPU_CORE2_FLAGS|CPU_SSE4_2_FLAGS|Rdtscp" },
40fb9820 84 { "CPU_K6_FLAGS",
4fdeb2a3 85 "186|286|386|486|586|SYSCALL|387|CPU_MMX_FLAGS" },
40fb9820 86 { "CPU_K6_2_FLAGS",
4fdeb2a3 87 "CPU_K6_FLAGS|3dnow" },
40fb9820 88 { "CPU_ATHLON_FLAGS",
4fdeb2a3 89 "CPU_K6_2_FLAGS|686|687|Nop|3dnowA" },
40fb9820 90 { "CPU_K8_FLAGS",
4fdeb2a3 91 "CPU_ATHLON_FLAGS|Rdtscp|CPU_SSE2_FLAGS|LM" },
40fb9820 92 { "CPU_AMDFAM10_FLAGS",
4fdeb2a3 93 "CPU_K8_FLAGS|FISTTP|CPU_SSE4A_FLAGS|LZCNT|POPCNT" },
68339fdf 94 { "CPU_BDVER1_FLAGS",
4fdeb2a3 95 "CPU_GENERIC64_FLAGS|FISTTP|Rdtscp|CX16|CPU_XOP_FLAGS|LZCNT|POPCNT|LWP|SVME|AES|PCLMUL|PRFCHW" },
4cab4add 96 { "CPU_BDVER2_FLAGS",
4fdeb2a3 97 "CPU_BDVER1_FLAGS|FMA|BMI|TBM|F16C" },
5e5c50d3 98 { "CPU_BDVER3_FLAGS",
4fdeb2a3 99 "CPU_BDVER2_FLAGS|Xsaveopt|FSGSBase" },
c7b0bd56 100 { "CPU_BDVER4_FLAGS",
4fdeb2a3 101 "CPU_BDVER3_FLAGS|AVX2|Movbe|BMI2|RdRnd|MWAITX" },
029f3522 102 { "CPU_ZNVER1_FLAGS",
4fdeb2a3 103 "CPU_GENERIC64_FLAGS|FISTTP|Rdtscp|CX16|CPU_AVX2_FLAGS|SSE4A|LZCNT|POPCNT|SVME|AES|PCLMUL|PRFCHW|FMA|BMI|F16C|Xsaveopt|FSGSBase|Movbe|BMI2|RdRnd|ADX|RdSeed|SMAP|SHA|XSAVEC|XSAVES|ClflushOpt|CLZERO|MWAITX" },
a9660a6f 104 { "CPU_ZNVER2_FLAGS",
4fdeb2a3 105 "CPU_ZNVER1_FLAGS|CLWB|RDPID|RDPRU|MCOMMIT|WBNOINVD" },
646cc3e0 106 { "CPU_ZNVER3_FLAGS",
4fdeb2a3 107 "CPU_ZNVER2_FLAGS|INVLPGB|TLBSYNC|VAES|VPCLMULQDQ|INVPCID|SNP|OSPKE" },
b0e8fa7f 108 { "CPU_ZNVER4_FLAGS",
4fdeb2a3 109 "CPU_ZNVER3_FLAGS|AVX512F|AVX512DQ|AVX512IFMA|AVX512CD|AVX512BW|AVX512VL|AVX512_BF16|AVX512VBMI|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_VPOPCNTDQ|GFNI|RMPQUERY" },
7b458c12 110 { "CPU_BTVER1_FLAGS",
4fdeb2a3 111 "CPU_GENERIC64_FLAGS|FISTTP|CX16|Rdtscp|CPU_SSSE3_FLAGS|SSE4A|LZCNT|POPCNT|PRFCHW|CX16|Clflush|FISTTP|SVME" },
7b458c12 112 { "CPU_BTVER2_FLAGS",
4fdeb2a3 113 "CPU_BTVER1_FLAGS|CPU_AVX_FLAGS|BMI|F16C|AES|PCLMUL|Movbe|Xsaveopt|PRFCHW" },
309d3373 114 { "CPU_8087_FLAGS",
4fdeb2a3 115 "8087" },
309d3373 116 { "CPU_287_FLAGS",
4fdeb2a3 117 "287" },
309d3373 118 { "CPU_387_FLAGS",
4fdeb2a3 119 "387" },
1848e567 120 { "CPU_687_FLAGS",
4fdeb2a3 121 "CPU_387_FLAGS|687" },
d871f3f4 122 { "CPU_CMOV_FLAGS",
4fdeb2a3 123 "CMOV" },
d871f3f4 124 { "CPU_FXSR_FLAGS",
4fdeb2a3 125 "FXSR" },
bd5295b2 126 { "CPU_CLFLUSH_FLAGS",
4fdeb2a3 127 "Clflush" },
22109423 128 { "CPU_NOP_FLAGS",
4fdeb2a3 129 "Nop" },
bd5295b2 130 { "CPU_SYSCALL_FLAGS",
4fdeb2a3 131 "SYSCALL" },
40fb9820 132 { "CPU_MMX_FLAGS",
4fdeb2a3 133 "MMX" },
40fb9820 134 { "CPU_SSE_FLAGS",
4fdeb2a3 135 "SSE" },
40fb9820 136 { "CPU_SSE2_FLAGS",
4fdeb2a3 137 "CPU_SSE_FLAGS|SSE2" },
40fb9820 138 { "CPU_SSE3_FLAGS",
4fdeb2a3 139 "CPU_SSE2_FLAGS|SSE3" },
40fb9820 140 { "CPU_SSSE3_FLAGS",
4fdeb2a3 141 "CPU_SSE3_FLAGS|SSSE3" },
40fb9820 142 { "CPU_SSE4_1_FLAGS",
4fdeb2a3 143 "CPU_SSSE3_FLAGS|SSE4_1" },
40fb9820 144 { "CPU_SSE4_2_FLAGS",
4fdeb2a3 145 "CPU_SSE4_1_FLAGS|SSE4_2|POPCNT" },
6305a203 146 { "CPU_VMX_FLAGS",
4fdeb2a3 147 "VMX" },
6305a203 148 { "CPU_SMX_FLAGS",
4fdeb2a3 149 "SMX" },
f03fe4c1 150 { "CPU_XSAVE_FLAGS",
4fdeb2a3 151 "Xsave" },
c7b8aa3a 152 { "CPU_XSAVEOPT_FLAGS",
4fdeb2a3 153 "CPU_XSAVE_FLAGS|Xsaveopt" },
c0f3af97 154 { "CPU_AES_FLAGS",
4fdeb2a3 155 "CPU_SSE2_FLAGS|AES" },
594ab6a3 156 { "CPU_PCLMUL_FLAGS",
4fdeb2a3 157 "CPU_SSE2_FLAGS|PCLMUL" },
c0f3af97 158 { "CPU_FMA_FLAGS",
4fdeb2a3 159 "CPU_AVX_FLAGS|FMA" },
922d8de8 160 { "CPU_FMA4_FLAGS",
4fdeb2a3 161 "CPU_AVX_FLAGS|FMA4" },
5dd85c99 162 { "CPU_XOP_FLAGS",
4fdeb2a3 163 "CPU_SSE4A_FLAGS|CPU_FMA4_FLAGS|XOP" },
f88c9eb0 164 { "CPU_LWP_FLAGS",
4fdeb2a3 165 "CPU_XSAVE_FLAGS|LWP" },
f12dc422 166 { "CPU_BMI_FLAGS",
4fdeb2a3 167 "BMI" },
2a2a0f38 168 { "CPU_TBM_FLAGS",
4fdeb2a3 169 "TBM" },
f1f8f695 170 { "CPU_MOVBE_FLAGS",
4fdeb2a3 171 "Movbe" },
60aa667e 172 { "CPU_CX16_FLAGS",
4fdeb2a3 173 "CX16" },
1b7f3fb0 174 { "CPU_RDTSCP_FLAGS",
4fdeb2a3 175 "Rdtscp" },
f1f8f695 176 { "CPU_EPT_FLAGS",
4fdeb2a3 177 "EPT" },
c7b8aa3a 178 { "CPU_FSGSBASE_FLAGS",
4fdeb2a3 179 "FSGSBase" },
c7b8aa3a 180 { "CPU_RDRND_FLAGS",
4fdeb2a3 181 "RdRnd" },
c7b8aa3a 182 { "CPU_F16C_FLAGS",
4fdeb2a3 183 "CPU_AVX_FLAGS|F16C" },
6c30d220 184 { "CPU_BMI2_FLAGS",
4fdeb2a3 185 "BMI2" },
6c30d220 186 { "CPU_LZCNT_FLAGS",
4fdeb2a3 187 "LZCNT" },
272a84b1 188 { "CPU_POPCNT_FLAGS",
4fdeb2a3 189 "POPCNT" },
42164a71 190 { "CPU_HLE_FLAGS",
4fdeb2a3 191 "HLE" },
42164a71 192 { "CPU_RTM_FLAGS",
4fdeb2a3 193 "RTM" },
6c30d220 194 { "CPU_INVPCID_FLAGS",
4fdeb2a3 195 "INVPCID" },
8729a6f6 196 { "CPU_VMFUNC_FLAGS",
4fdeb2a3 197 "VMFUNC" },
40fb9820 198 { "CPU_3DNOW_FLAGS",
4fdeb2a3 199 "CPU_MMX_FLAGS|3dnow" },
40fb9820 200 { "CPU_3DNOWA_FLAGS",
4fdeb2a3 201 "CPU_3DNOW_FLAGS|3dnowA" },
40fb9820 202 { "CPU_PADLOCK_FLAGS",
4fdeb2a3 203 "PadLock" },
40fb9820 204 { "CPU_SVME_FLAGS",
4fdeb2a3 205 "SVME" },
40fb9820 206 { "CPU_SSE4A_FLAGS",
4fdeb2a3 207 "CPU_SSE3_FLAGS|SSE4a" },
40fb9820 208 { "CPU_ABM_FLAGS",
4fdeb2a3 209 "LZCNT|POPCNT" },
c0f3af97 210 { "CPU_AVX_FLAGS",
4fdeb2a3 211 "CPU_SSE4_2_FLAGS|CPU_XSAVE_FLAGS|AVX" },
6c30d220 212 { "CPU_AVX2_FLAGS",
4fdeb2a3 213 "CPU_AVX_FLAGS|AVX2" },
58bf9b6a 214 { "CPU_AVX_VNNI_FLAGS",
4fdeb2a3 215 "CPU_AVX2_FLAGS|AVX_VNNI" },
43234a1e 216 { "CPU_AVX512F_FLAGS",
4fdeb2a3 217 "CPU_AVX2_FLAGS|AVX512F" },
43234a1e 218 { "CPU_AVX512CD_FLAGS",
4fdeb2a3 219 "CPU_AVX512F_FLAGS|AVX512CD" },
43234a1e 220 { "CPU_AVX512ER_FLAGS",
4fdeb2a3 221 "CPU_AVX512F_FLAGS|AVX512ER" },
43234a1e 222 { "CPU_AVX512PF_FLAGS",
4fdeb2a3 223 "CPU_AVX512F_FLAGS|AVX512PF" },
f3ad7637 224 { "CPU_AVX512DQ_FLAGS",
4fdeb2a3 225 "CPU_AVX512F_FLAGS|AVX512DQ" },
f3ad7637 226 { "CPU_AVX512BW_FLAGS",
4fdeb2a3 227 "CPU_AVX512F_FLAGS|AVX512BW" },
f3ad7637 228 { "CPU_AVX512VL_FLAGS",
4fdeb2a3 229 "CPU_AVX512F_FLAGS|AVX512VL" },
f3ad7637 230 { "CPU_AVX512IFMA_FLAGS",
4fdeb2a3 231 "CPU_AVX512F_FLAGS|AVX512IFMA" },
f3ad7637 232 { "CPU_AVX512VBMI_FLAGS",
4fdeb2a3 233 "CPU_AVX512F_FLAGS|AVX512VBMI" },
920d2ddc 234 { "CPU_AVX512_4FMAPS_FLAGS",
4fdeb2a3 235 "CPU_AVX512F_FLAGS|AVX512_4FMAPS" },
47acf0bd 236 { "CPU_AVX512_4VNNIW_FLAGS",
4fdeb2a3 237 "CPU_AVX512F_FLAGS|AVX512_4VNNIW" },
620214f7 238 { "CPU_AVX512_VPOPCNTDQ_FLAGS",
4fdeb2a3 239 "CPU_AVX512F_FLAGS|AVX512_VPOPCNTDQ" },
53467f57 240 { "CPU_AVX512_VBMI2_FLAGS",
4fdeb2a3 241 "CPU_AVX512F_FLAGS|AVX512_VBMI2" },
8cfcb765 242 { "CPU_AVX512_VNNI_FLAGS",
4fdeb2a3 243 "CPU_AVX512F_FLAGS|AVX512_VNNI" },
ee6872be 244 { "CPU_AVX512_BITALG_FLAGS",
4fdeb2a3 245 "CPU_AVX512F_FLAGS|AVX512_BITALG" },
d6aab7a1 246 { "CPU_AVX512_BF16_FLAGS",
4fdeb2a3 247 "CPU_AVX512F_FLAGS|AVX512_BF16" },
0cc78721 248 { "CPU_AVX512_FP16_FLAGS",
4fdeb2a3 249 "CPU_AVX512BW_FLAGS|AVX512_FP16" },
ef07be45 250 { "CPU_PREFETCHI_FLAGS",
4fdeb2a3 251 "PREFETCHI"},
4321af3e 252 { "CPU_AVX_IFMA_FLAGS",
4fdeb2a3 253 "CPU_AVX2_FLAGS|AVX_IFMA" },
23ae61ad 254 { "CPU_AVX_VNNI_INT8_FLAGS",
4fdeb2a3 255 "CPU_AVX2_FLAGS|AVX_VNNI_INT8" },
a93e3234 256 { "CPU_CMPCCXADD_FLAGS",
4fdeb2a3 257 "CMPCCXADD" },
941f0833 258 { "CPU_WRMSRNS_FLAGS",
4fdeb2a3 259 "WRMSRNS" },
2188d6ea 260 { "CPU_MSRLIST_FLAGS",
4fdeb2a3 261 "MSRLIST" },
01d8ce74 262 { "CPU_AVX_NE_CONVERT_FLAGS",
4fdeb2a3 263 "CPU_AVX2_FLAGS|AVX_NE_CONVERT" },
b06311ad 264 { "CPU_RAO_INT_FLAGS",
4fdeb2a3 265 "RAO_INT" },
7b6d09fb 266 { "CPU_IAMCU_FLAGS",
4fdeb2a3 267 "186|286|386|486|586|IAMCU" },
e2e1fcde 268 { "CPU_ADX_FLAGS",
4fdeb2a3 269 "ADX" },
e2e1fcde 270 { "CPU_RDSEED_FLAGS",
4fdeb2a3 271 "RdSeed" },
e2e1fcde 272 { "CPU_PRFCHW_FLAGS",
4fdeb2a3 273 "PRFCHW" },
5c111e37 274 { "CPU_SMAP_FLAGS",
4fdeb2a3 275 "SMAP" },
7e8b059b 276 { "CPU_MPX_FLAGS",
4fdeb2a3 277 "CPU_XSAVE_FLAGS|MPX" },
a0046408 278 { "CPU_SHA_FLAGS",
4fdeb2a3 279 "CPU_SSE2_FLAGS|SHA" },
963f3586 280 { "CPU_CLFLUSHOPT_FLAGS",
4fdeb2a3 281 "ClflushOpt" },
963f3586 282 { "CPU_XSAVES_FLAGS",
4fdeb2a3 283 "CPU_XSAVE_FLAGS|XSAVES" },
963f3586 284 { "CPU_XSAVEC_FLAGS",
4fdeb2a3 285 "CPU_XSAVE_FLAGS|XSAVEC" },
dcf893b5 286 { "CPU_PREFETCHWT1_FLAGS",
4fdeb2a3 287 "PREFETCHWT1" },
2cf200a4 288 { "CPU_SE1_FLAGS",
4fdeb2a3 289 "SE1" },
c5e7287a 290 { "CPU_CLWB_FLAGS",
4fdeb2a3 291 "CLWB" },
029f3522 292 { "CPU_CLZERO_FLAGS",
4fdeb2a3 293 "CLZERO" },
9916071f 294 { "CPU_MWAITX_FLAGS",
4fdeb2a3 295 "MWAITX" },
8eab4136 296 { "CPU_OSPKE_FLAGS",
4fdeb2a3 297 "CPU_XSAVE_FLAGS|OSPKE" },
8bc52696 298 { "CPU_RDPID_FLAGS",
4fdeb2a3 299 "RDPID" },
6b40c462 300 { "CPU_PTWRITE_FLAGS",
4fdeb2a3 301 "PTWRITE" },
d777820b 302 { "CPU_IBT_FLAGS",
4fdeb2a3 303 "IBT" },
d777820b 304 { "CPU_SHSTK_FLAGS",
4fdeb2a3 305 "SHSTK" },
48521003 306 { "CPU_GFNI_FLAGS",
4fdeb2a3 307 "GFNI" },
8dcf1fad 308 { "CPU_VAES_FLAGS",
4fdeb2a3 309 "VAES" },
ff1982d5 310 { "CPU_VPCLMULQDQ_FLAGS",
4fdeb2a3 311 "VPCLMULQDQ" },
3233d7d0 312 { "CPU_WBNOINVD_FLAGS",
4fdeb2a3 313 "WBNOINVD" },
be3a8dca 314 { "CPU_PCONFIG_FLAGS",
4fdeb2a3 315 "PCONFIG" },
de89d0a3 316 { "CPU_WAITPKG_FLAGS",
4fdeb2a3 317 "WAITPKG" },
f64c42a9 318 { "CPU_UINTR_FLAGS",
4fdeb2a3 319 "UINTR" },
c48935d7 320 { "CPU_CLDEMOTE_FLAGS",
4fdeb2a3 321 "CLDEMOTE" },
260cd341 322 { "CPU_AMX_INT8_FLAGS",
4fdeb2a3 323 "CPU_AMX_TILE_FLAGS|AMX_INT8" },
260cd341 324 { "CPU_AMX_BF16_FLAGS",
4fdeb2a3 325 "CPU_AMX_TILE_FLAGS|AMX_BF16" },
68830fba 326 { "CPU_AMX_FP16_FLAGS",
4fdeb2a3 327 "CPU_AMX_TILE_FLAGS|AMX_FP16" },
260cd341 328 { "CPU_AMX_TILE_FLAGS",
4fdeb2a3 329 "AMX_TILE" },
c0a30a9f 330 { "CPU_MOVDIRI_FLAGS",
4fdeb2a3 331 "MOVDIRI" },
c0a30a9f 332 { "CPU_MOVDIR64B_FLAGS",
4fdeb2a3 333 "MOVDIR64B" },
5d79adc4 334 { "CPU_ENQCMD_FLAGS",
4fdeb2a3 335 "ENQCMD" },
4b27d27c 336 { "CPU_SERIALIZE_FLAGS",
4fdeb2a3 337 "SERIALIZE" },
9186c494 338 { "CPU_AVX512_VP2INTERSECT_FLAGS",
4fdeb2a3 339 "AVX512_VP2INTERSECT" },
81d54bb7 340 { "CPU_TDX_FLAGS",
4fdeb2a3 341 "TDX" },
142861df 342 { "CPU_RDPRU_FLAGS",
4fdeb2a3 343 "RDPRU" },
142861df 344 { "CPU_MCOMMIT_FLAGS",
4fdeb2a3 345 "MCOMMIT" },
a847e322 346 { "CPU_SEV_ES_FLAGS",
4fdeb2a3 347 "SEV_ES" },
bb651e8b 348 { "CPU_TSXLDTRK_FLAGS",
4fdeb2a3 349 "TSXLDTRK"},
c4694f17 350 { "CPU_KL_FLAGS",
4fdeb2a3 351 "KL" },
c4694f17 352 { "CPU_WIDEKL_FLAGS",
4fdeb2a3 353 "WideKL" },
c1fa250a 354 { "CPU_HRESET_FLAGS",
4fdeb2a3 355 "HRESET"},
646cc3e0 356 { "CPU_INVLPGB_FLAGS",
4fdeb2a3 357 "INVLPGB" },
646cc3e0 358 { "CPU_TLBSYNC_FLAGS",
4fdeb2a3 359 "TLBSYNC" },
646cc3e0 360 { "CPU_SNP_FLAGS",
4fdeb2a3 361 "SNP" },
b0e8fa7f 362 { "CPU_RMPQUERY_FLAGS",
4fdeb2a3 363 "RMPQUERY" },
1848e567 364 { "CPU_ANY_X87_FLAGS",
4fdeb2a3 365 "CPU_ANY_287_FLAGS|8087" },
1848e567 366 { "CPU_ANY_287_FLAGS",
4fdeb2a3 367 "CPU_ANY_387_FLAGS|287" },
1848e567 368 { "CPU_ANY_387_FLAGS",
4fdeb2a3 369 "CPU_ANY_687_FLAGS|387" },
1848e567 370 { "CPU_ANY_687_FLAGS",
4fdeb2a3 371 "687|FISTTP" },
d871f3f4 372 { "CPU_ANY_CMOV_FLAGS",
4fdeb2a3 373 "CMOV" },
d871f3f4 374 { "CPU_ANY_FXSR_FLAGS",
4fdeb2a3 375 "FXSR" },
1848e567
L
376 { "CPU_ANY_MMX_FLAGS",
377 "CPU_3DNOWA_FLAGS" },
378 { "CPU_ANY_SSE_FLAGS",
4fdeb2a3 379 "CPU_ANY_SSE2_FLAGS|SSE" },
1848e567 380 { "CPU_ANY_SSE2_FLAGS",
4fdeb2a3 381 "CPU_ANY_SSE3_FLAGS|SSE2" },
1848e567 382 { "CPU_ANY_SSE3_FLAGS",
4fdeb2a3 383 "CPU_ANY_SSSE3_FLAGS|SSE3|SSE4a" },
1848e567 384 { "CPU_ANY_SSSE3_FLAGS",
4fdeb2a3 385 "CPU_ANY_SSE4_1_FLAGS|SSSE3" },
1848e567 386 { "CPU_ANY_SSE4_1_FLAGS",
4fdeb2a3 387 "CPU_ANY_SSE4_2_FLAGS|SSE4_1" },
1848e567 388 { "CPU_ANY_SSE4_2_FLAGS",
4fdeb2a3 389 "SSE4_2" },
dabec65d 390 { "CPU_ANY_SSE4A_FLAGS",
4fdeb2a3 391 "SSE4a" },
1848e567 392 { "CPU_ANY_AVX_FLAGS",
4fdeb2a3 393 "CPU_ANY_AVX2_FLAGS|F16C|FMA|FMA4|XOP|AVX" },
1848e567 394 { "CPU_ANY_AVX2_FLAGS",
4fdeb2a3 395 "CPU_ANY_AVX512F_FLAGS|AVX2|AVX_VNNI|AVX_IFMA|AVX_VNNI_INT8|AVX_NE_CONVERT" },
144b71e2 396 { "CPU_ANY_AVX512F_FLAGS",
4fdeb2a3 397 "AVX512F|AVX512CD|AVX512ER|AVX512PF|AVX512DQ|CPU_ANY_AVX512BW_FLAGS|AVX512VL|AVX512IFMA|AVX512VBMI|AVX512_4FMAPS|AVX512_4VNNIW|AVX512_VPOPCNTDQ|AVX512_VBMI2|AVX512_VNNI|AVX512_BITALG|AVX512_BF16|AVX512_VP2INTERSECT" },
144b71e2 398 { "CPU_ANY_AVX512CD_FLAGS",
4fdeb2a3 399 "AVX512CD" },
144b71e2 400 { "CPU_ANY_AVX512ER_FLAGS",
4fdeb2a3 401 "AVX512ER" },
144b71e2 402 { "CPU_ANY_AVX512PF_FLAGS",
4fdeb2a3 403 "AVX512PF" },
144b71e2 404 { "CPU_ANY_AVX512DQ_FLAGS",
4fdeb2a3 405 "AVX512DQ" },
144b71e2 406 { "CPU_ANY_AVX512BW_FLAGS",
4fdeb2a3 407 "AVX512BW|CPU_ANY_AVX512_FP16_FLAGS" },
144b71e2 408 { "CPU_ANY_AVX512VL_FLAGS",
4fdeb2a3 409 "AVX512VL" },
144b71e2 410 { "CPU_ANY_AVX512IFMA_FLAGS",
4fdeb2a3 411 "AVX512IFMA" },
144b71e2 412 { "CPU_ANY_AVX512VBMI_FLAGS",
4fdeb2a3 413 "AVX512VBMI" },
920d2ddc 414 { "CPU_ANY_AVX512_4FMAPS_FLAGS",
4fdeb2a3 415 "AVX512_4FMAPS" },
47acf0bd 416 { "CPU_ANY_AVX512_4VNNIW_FLAGS",
4fdeb2a3 417 "AVX512_4VNNIW" },
620214f7 418 { "CPU_ANY_AVX512_VPOPCNTDQ_FLAGS",
4fdeb2a3 419 "AVX512_VPOPCNTDQ" },
d777820b 420 { "CPU_ANY_IBT_FLAGS",
4fdeb2a3 421 "IBT" },
d777820b 422 { "CPU_ANY_SHSTK_FLAGS",
4fdeb2a3 423 "SHSTK" },
53467f57 424 { "CPU_ANY_AVX512_VBMI2_FLAGS",
4fdeb2a3 425 "AVX512_VBMI2" },
8cfcb765 426 { "CPU_ANY_AVX512_VNNI_FLAGS",
4fdeb2a3 427 "AVX512_VNNI" },
ee6872be 428 { "CPU_ANY_AVX512_BITALG_FLAGS",
4fdeb2a3 429 "AVX512_BITALG" },
d6aab7a1 430 { "CPU_ANY_AVX512_BF16_FLAGS",
4fdeb2a3 431 "AVX512_BF16" },
260cd341 432 { "CPU_ANY_AMX_INT8_FLAGS",
4fdeb2a3 433 "AMX_INT8" },
260cd341 434 { "CPU_ANY_AMX_BF16_FLAGS",
4fdeb2a3 435 "AMX_BF16" },
260cd341 436 { "CPU_ANY_AMX_TILE_FLAGS",
4fdeb2a3 437 "AMX_TILE|AMX_INT8|AMX_BF16|AMX_FP16" },
58bf9b6a 438 { "CPU_ANY_AVX_VNNI_FLAGS",
4fdeb2a3 439 "AVX_VNNI" },
c0a30a9f 440 { "CPU_ANY_MOVDIRI_FLAGS",
4fdeb2a3 441 "MOVDIRI" },
f64c42a9 442 { "CPU_ANY_UINTR_FLAGS",
4fdeb2a3 443 "UINTR" },
c0a30a9f 444 { "CPU_ANY_MOVDIR64B_FLAGS",
4fdeb2a3 445 "MOVDIR64B" },
5d79adc4 446 { "CPU_ANY_ENQCMD_FLAGS",
4fdeb2a3 447 "ENQCMD" },
4b27d27c 448 { "CPU_ANY_SERIALIZE_FLAGS",
4fdeb2a3 449 "SERIALIZE" },
9186c494 450 { "CPU_ANY_AVX512_VP2INTERSECT_FLAGS",
4fdeb2a3 451 "AVX512_VP2INTERSECT" },
81d54bb7 452 { "CPU_ANY_TDX_FLAGS",
4fdeb2a3 453 "TDX" },
bb651e8b 454 { "CPU_ANY_TSXLDTRK_FLAGS",
4fdeb2a3 455 "TSXLDTRK" },
c4694f17 456 { "CPU_ANY_KL_FLAGS",
4fdeb2a3 457 "KL|WideKL" },
c4694f17 458 { "CPU_ANY_WIDEKL_FLAGS",
4fdeb2a3 459 "WideKL" },
c1fa250a 460 { "CPU_ANY_HRESET_FLAGS",
4fdeb2a3 461 "HRESET" },
0cc78721 462 { "CPU_ANY_AVX512_FP16_FLAGS",
4fdeb2a3 463 "AVX512_FP16" },
4321af3e 464 { "CPU_ANY_AVX_IFMA_FLAGS",
4fdeb2a3 465 "AVX_IFMA" },
23ae61ad 466 { "CPU_ANY_AVX_VNNI_INT8_FLAGS",
4fdeb2a3 467 "AVX_VNNI_INT8" },
a93e3234 468 { "CPU_ANY_CMPCCXADD_FLAGS",
4fdeb2a3 469 "CMPCCXADD" },
941f0833 470 { "CPU_ANY_WRMSRNS_FLAGS",
4fdeb2a3 471 "WRMSRNS" },
2188d6ea 472 { "CPU_ANY_MSRLIST_FLAGS",
4fdeb2a3 473 "MSRLIST" },
01d8ce74 474 { "CPU_ANY_AVX_NE_CONVERT_FLAGS",
4fdeb2a3 475 "AVX_NE_CONVERT" },
b06311ad 476 { "CPU_ANY_RAO_INT_FLAGS",
4fdeb2a3 477 "RAO_INT"},
40fb9820
L
478};
479
40fb9820
L
480typedef struct bitfield
481{
482 int position;
483 int value;
484 const char *name;
485} bitfield;
486
4fdeb2a3 487#define BITFIELD(n) { Cpu##n, 0, #n }
40fb9820
L
488
489static bitfield cpu_flags[] =
490{
4fdeb2a3
JB
491 BITFIELD (186),
492 BITFIELD (286),
493 BITFIELD (386),
494 BITFIELD (486),
495 BITFIELD (586),
496 BITFIELD (686),
497 BITFIELD (CMOV),
498 BITFIELD (FXSR),
499 BITFIELD (Clflush),
500 BITFIELD (Nop),
501 BITFIELD (SYSCALL),
502 BITFIELD (8087),
503 BITFIELD (287),
504 BITFIELD (387),
505 BITFIELD (687),
506 BITFIELD (FISTTP),
507 BITFIELD (MMX),
508 BITFIELD (SSE),
509 BITFIELD (SSE2),
510 BITFIELD (SSE3),
511 BITFIELD (SSSE3),
512 BITFIELD (SSE4_1),
513 BITFIELD (SSE4_2),
514 BITFIELD (AVX),
515 BITFIELD (AVX2),
516 BITFIELD (AVX512F),
517 BITFIELD (AVX512CD),
518 BITFIELD (AVX512ER),
519 BITFIELD (AVX512PF),
520 BITFIELD (AVX512VL),
521 BITFIELD (AVX512DQ),
522 BITFIELD (AVX512BW),
523 BITFIELD (IAMCU),
524 BITFIELD (SSE4a),
525 BITFIELD (3dnow),
526 BITFIELD (3dnowA),
527 BITFIELD (PadLock),
528 BITFIELD (SVME),
529 BITFIELD (VMX),
530 BITFIELD (SMX),
531 BITFIELD (Xsave),
532 BITFIELD (Xsaveopt),
533 BITFIELD (AES),
534 BITFIELD (PCLMUL),
535 BITFIELD (FMA),
536 BITFIELD (FMA4),
537 BITFIELD (XOP),
538 BITFIELD (LWP),
539 BITFIELD (BMI),
540 BITFIELD (TBM),
541 BITFIELD (LM),
542 BITFIELD (Movbe),
543 BITFIELD (CX16),
544 BITFIELD (EPT),
545 BITFIELD (Rdtscp),
546 BITFIELD (FSGSBase),
547 BITFIELD (RdRnd),
548 BITFIELD (F16C),
549 BITFIELD (BMI2),
550 BITFIELD (LZCNT),
551 BITFIELD (POPCNT),
552 BITFIELD (HLE),
553 BITFIELD (RTM),
554 BITFIELD (INVPCID),
555 BITFIELD (VMFUNC),
556 BITFIELD (RDSEED),
557 BITFIELD (ADX),
558 BITFIELD (PRFCHW),
559 BITFIELD (SMAP),
560 BITFIELD (SHA),
561 BITFIELD (ClflushOpt),
562 BITFIELD (XSAVES),
563 BITFIELD (XSAVEC),
564 BITFIELD (PREFETCHWT1),
565 BITFIELD (SE1),
566 BITFIELD (CLWB),
567 BITFIELD (MPX),
568 BITFIELD (AVX512IFMA),
569 BITFIELD (AVX512VBMI),
570 BITFIELD (AVX512_4FMAPS),
571 BITFIELD (AVX512_4VNNIW),
572 BITFIELD (AVX512_VPOPCNTDQ),
573 BITFIELD (AVX512_VBMI2),
574 BITFIELD (AVX512_VNNI),
575 BITFIELD (AVX512_BITALG),
576 BITFIELD (AVX512_BF16),
577 BITFIELD (AVX512_VP2INTERSECT),
578 BITFIELD (TDX),
579 BITFIELD (AVX_VNNI),
580 BITFIELD (AVX512_FP16),
581 BITFIELD (PREFETCHI),
582 BITFIELD (AVX_IFMA),
583 BITFIELD (AVX_VNNI_INT8),
584 BITFIELD (CMPCCXADD),
585 BITFIELD (WRMSRNS),
586 BITFIELD (MSRLIST),
587 BITFIELD (AVX_NE_CONVERT),
588 BITFIELD (RAO_INT),
589 BITFIELD (MWAITX),
590 BITFIELD (CLZERO),
591 BITFIELD (OSPKE),
592 BITFIELD (RDPID),
593 BITFIELD (PTWRITE),
594 BITFIELD (IBT),
595 BITFIELD (SHSTK),
596 BITFIELD (GFNI),
597 BITFIELD (VAES),
598 BITFIELD (VPCLMULQDQ),
599 BITFIELD (WBNOINVD),
600 BITFIELD (PCONFIG),
601 BITFIELD (WAITPKG),
602 BITFIELD (UINTR),
603 BITFIELD (CLDEMOTE),
604 BITFIELD (AMX_INT8),
605 BITFIELD (AMX_BF16),
606 BITFIELD (AMX_FP16),
607 BITFIELD (AMX_TILE),
608 BITFIELD (MOVDIRI),
609 BITFIELD (MOVDIR64B),
610 BITFIELD (ENQCMD),
611 BITFIELD (SERIALIZE),
612 BITFIELD (RDPRU),
613 BITFIELD (MCOMMIT),
614 BITFIELD (SEV_ES),
615 BITFIELD (TSXLDTRK),
616 BITFIELD (KL),
617 BITFIELD (WideKL),
618 BITFIELD (HRESET),
619 BITFIELD (INVLPGB),
620 BITFIELD (TLBSYNC),
621 BITFIELD (SNP),
622 BITFIELD (RMPQUERY),
623 BITFIELD (64),
624 BITFIELD (No64),
40fb9820 625#ifdef CpuUnused
4fdeb2a3 626 BITFIELD (Unused),
40fb9820
L
627#endif
628};
629
4fdeb2a3
JB
630#undef BITFIELD
631#define BITFIELD(n) { n, 0, #n }
632
40fb9820
L
633static bitfield opcode_modifiers[] =
634{
635 BITFIELD (D),
636 BITFIELD (W),
86fa6981 637 BITFIELD (Load),
40fb9820 638 BITFIELD (Modrm),
40fb9820 639 BITFIELD (Jump),
40fb9820 640 BITFIELD (FloatMF),
673fe0f0 641 BITFIELD (Size),
9c19e9ec 642 BITFIELD (CheckOperandSize),
255571cd 643 BITFIELD (OperandConstraint),
3cd7f3e3 644 BITFIELD (MnemonicSize),
40fb9820
L
645 BITFIELD (No_bSuf),
646 BITFIELD (No_wSuf),
647 BITFIELD (No_lSuf),
648 BITFIELD (No_sSuf),
649 BITFIELD (No_qSuf),
40fb9820
L
650 BITFIELD (FWait),
651 BITFIELD (IsString),
dfd69174 652 BITFIELD (RegMem),
7e8b059b 653 BITFIELD (BNDPrefixOk),
742732c7 654 BITFIELD (PrefixOk),
40fb9820
L
655 BITFIELD (IsPrefix),
656 BITFIELD (ImmExt),
657 BITFIELD (NoRex64),
c0f3af97 658 BITFIELD (Vex),
2426c15f 659 BITFIELD (VexVVVV),
1ef99a7b 660 BITFIELD (VexW),
441f6aca 661 BITFIELD (OpcodeSpace),
7b47a312 662 BITFIELD (OpcodePrefix),
8cd7925b 663 BITFIELD (VexSources),
63112cd6 664 BITFIELD (SIB),
c0f3af97 665 BITFIELD (SSE2AVX),
43234a1e
L
666 BITFIELD (EVex),
667 BITFIELD (Masking),
43234a1e
L
668 BITFIELD (Broadcast),
669 BITFIELD (StaticRounding),
670 BITFIELD (SAE),
671 BITFIELD (Disp8MemShift),
b6f8c7c4 672 BITFIELD (Optimize),
1efbbeb4 673 BITFIELD (ATTMnemonic),
e1d4d893 674 BITFIELD (ATTSyntax),
5c07affc 675 BITFIELD (IntelSyntax),
4b5aaf5f 676 BITFIELD (ISA64),
40fb9820
L
677};
678
bab6aec1
JB
679#define CLASS(n) #n, n
680
681static const struct {
682 const char *name;
683 enum operand_class value;
684} operand_classes[] = {
685 CLASS (Reg),
00cee14f 686 CLASS (SReg),
4a5c67ed
JB
687 CLASS (RegCR),
688 CLASS (RegDR),
689 CLASS (RegTR),
3528c362
JB
690 CLASS (RegMMX),
691 CLASS (RegSIMD),
f74a6307
JB
692 CLASS (RegMask),
693 CLASS (RegBND),
bab6aec1
JB
694};
695
696#undef CLASS
697
75e5731b
JB
698#define INSTANCE(n) #n, n
699
700static const struct {
701 const char *name;
702 enum operand_instance value;
703} operand_instances[] = {
704 INSTANCE (Accum),
705 INSTANCE (RegC),
706 INSTANCE (RegD),
474da251 707 INSTANCE (RegB),
75e5731b
JB
708};
709
710#undef INSTANCE
711
40fb9820
L
712static bitfield operand_types[] =
713{
94ff3a50 714 BITFIELD (Imm1),
40fb9820
L
715 BITFIELD (Imm8),
716 BITFIELD (Imm8S),
717 BITFIELD (Imm16),
718 BITFIELD (Imm32),
719 BITFIELD (Imm32S),
720 BITFIELD (Imm64),
40fb9820
L
721 BITFIELD (BaseIndex),
722 BITFIELD (Disp8),
723 BITFIELD (Disp16),
724 BITFIELD (Disp32),
40fb9820 725 BITFIELD (Disp64),
7d5e4556
L
726 BITFIELD (Byte),
727 BITFIELD (Word),
728 BITFIELD (Dword),
729 BITFIELD (Fword),
730 BITFIELD (Qword),
731 BITFIELD (Tbyte),
732 BITFIELD (Xmmword),
c0f3af97 733 BITFIELD (Ymmword),
43234a1e 734 BITFIELD (Zmmword),
260cd341 735 BITFIELD (Tmmword),
7d5e4556 736 BITFIELD (Unspecified),
40fb9820
L
737#ifdef OTUnused
738 BITFIELD (OTUnused),
739#endif
740};
741
3d4d5afa 742static const char *filename;
7ac20022
JB
743static i386_cpu_flags active_cpu_flags;
744static int active_isstring;
3d4d5afa 745
4c4898e8
JB
746struct template_arg {
747 const struct template_arg *next;
748 const char *val;
749};
750
751struct template_instance {
752 const struct template_instance *next;
753 const char *name;
754 const struct template_arg *args;
755};
756
757struct template_param {
758 const struct template_param *next;
759 const char *name;
760};
761
762struct template {
e07ae9a3 763 struct template *next;
4c4898e8
JB
764 const char *name;
765 const struct template_instance *instances;
766 const struct template_param *params;
767};
768
e07ae9a3 769static struct template *templates;
4c4898e8 770
40fb9820
L
771static int
772compare (const void *x, const void *y)
773{
774 const bitfield *xp = (const bitfield *) x;
775 const bitfield *yp = (const bitfield *) y;
776 return xp->position - yp->position;
777}
778
40b8e679
L
779static void
780fail (const char *message, ...)
781{
782 va_list args;
29c048b6 783
40b8e679 784 va_start (args, message);
a6743a54 785 fprintf (stderr, _("%s: error: "), program_name);
40b8e679
L
786 vfprintf (stderr, message, args);
787 va_end (args);
788 xexit (1);
789}
790
72ffa0fb
L
791static void
792process_copyright (FILE *fp)
793{
794 fprintf (fp, "/* This file is automatically generated by i386-gen. Do not edit! */\n\
a2c58332 795/* Copyright (C) 2007-2022 Free Software Foundation, Inc.\n\
72ffa0fb
L
796\n\
797 This file is part of the GNU opcodes library.\n\
798\n\
799 This library is free software; you can redistribute it and/or modify\n\
800 it under the terms of the GNU General Public License as published by\n\
801 the Free Software Foundation; either version 3, or (at your option)\n\
802 any later version.\n\
803\n\
804 It is distributed in the hope that it will be useful, but WITHOUT\n\
805 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n\
806 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public\n\
807 License for more details.\n\
808\n\
809 You should have received a copy of the GNU General Public License\n\
810 along with this program; if not, write to the Free Software\n\
811 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,\n\
812 MA 02110-1301, USA. */\n");
813}
814
40b8e679
L
815/* Remove leading white spaces. */
816
817static char *
818remove_leading_whitespaces (char *str)
819{
820 while (ISSPACE (*str))
821 str++;
822 return str;
823}
824
825/* Remove trailing white spaces. */
826
827static void
828remove_trailing_whitespaces (char *str)
829{
830 size_t last = strlen (str);
831
832 if (last == 0)
833 return;
834
835 do
836 {
837 last--;
838 if (ISSPACE (str [last]))
839 str[last] = '\0';
840 else
841 break;
842 }
843 while (last != 0);
844}
845
93b1ec2c 846/* Find next field separated by SEP and terminate it. Return a
40b8e679
L
847 pointer to the one after it. */
848
849static char *
c587b3f9 850next_field (char *str, char sep, char **next, char *last)
40b8e679
L
851{
852 char *p;
853
854 p = remove_leading_whitespaces (str);
93b1ec2c 855 for (str = p; *str != sep && *str != '\0'; str++);
40b8e679
L
856
857 *str = '\0';
858 remove_trailing_whitespaces (p);
859
29c048b6 860 *next = str + 1;
40b8e679 861
c587b3f9
L
862 if (p >= last)
863 abort ();
864
40b8e679
L
865 return p;
866}
867
1848e567
L
868static void set_bitfield (char *, bitfield *, int, unsigned int, int);
869
870static int
3cc17af5
JB
871set_bitfield_from_cpu_flag_init (char *f, bitfield *array, unsigned int size,
872 int lineno)
1848e567
L
873{
874 char *str, *next, *last;
875 unsigned int i;
876
877 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
878 if (strcmp (cpu_flag_init[i].name, f) == 0)
879 {
880 /* Turn on selective bits. */
881 char *init = xstrdup (cpu_flag_init[i].init);
882 last = init + strlen (init);
883 for (next = init; next && next < last; )
884 {
885 str = next_field (next, '|', &next, last);
886 if (str)
887 set_bitfield (str, array, 1, size, lineno);
888 }
889 free (init);
890 return 0;
891 }
892
893 return -1;
894}
895
40fb9820 896static void
1848e567 897set_bitfield (char *f, bitfield *array, int value,
8a9036a4 898 unsigned int size, int lineno)
40fb9820
L
899{
900 unsigned int i;
901
3677e4c1
JB
902 /* Ignore empty fields; they may result from template expansions. */
903 if (*f == '\0')
904 return;
905
40fb9820
L
906 for (i = 0; i < size; i++)
907 if (strcasecmp (array[i].name, f) == 0)
908 {
8a9036a4 909 array[i].value = value;
40fb9820
L
910 return;
911 }
912
2bf05e57
L
913 if (value)
914 {
915 const char *v = strchr (f, '=');
916
917 if (v)
918 {
919 size_t n = v - f;
920 char *end;
921
922 for (i = 0; i < size; i++)
923 if (strncasecmp (array[i].name, f, n) == 0)
924 {
925 value = strtol (v + 1, &end, 0);
926 if (*end == '\0')
927 {
928 array[i].value = value;
929 return;
930 }
931 break;
932 }
933 }
934 }
935
3cc17af5
JB
936 /* Handle CPU_XXX_FLAGS. */
937 if (value == 1 && !set_bitfield_from_cpu_flag_init (f, array, size, lineno))
1848e567
L
938 return;
939
bd5295b2 940 if (lineno != -1)
a6743a54 941 fail (_("%s: %d: unknown bitfield: %s\n"), filename, lineno, f);
bd5295b2 942 else
a6743a54 943 fail (_("unknown bitfield: %s\n"), f);
40fb9820
L
944}
945
946static void
947output_cpu_flags (FILE *table, bitfield *flags, unsigned int size,
948 int macro, const char *comma, const char *indent)
949{
950 unsigned int i;
951
7ac20022
JB
952 memset (&active_cpu_flags, 0, sizeof(active_cpu_flags));
953
40fb9820
L
954 fprintf (table, "%s{ { ", indent);
955
956 for (i = 0; i < size - 1; i++)
957 {
10632b79
L
958 if (((i + 1) % 20) != 0)
959 fprintf (table, "%d, ", flags[i].value);
960 else
961 fprintf (table, "%d,", flags[i].value);
40fb9820
L
962 if (((i + 1) % 20) == 0)
963 {
964 /* We need \\ for macro. */
965 if (macro)
966 fprintf (table, " \\\n %s", indent);
967 else
968 fprintf (table, "\n %s", indent);
969 }
7ac20022
JB
970 if (flags[i].value)
971 active_cpu_flags.array[i / 32] |= 1U << (i % 32);
40fb9820
L
972 }
973
974 fprintf (table, "%d } }%s\n", flags[i].value, comma);
975}
976
977static void
978process_i386_cpu_flag (FILE *table, char *flag, int macro,
bd5295b2
L
979 const char *comma, const char *indent,
980 int lineno)
40fb9820 981{
ad9de929 982 char *str, *next = flag, *last;
8a9036a4 983 unsigned int i;
ad9de929 984 int value = 1;
40fb9820
L
985 bitfield flags [ARRAY_SIZE (cpu_flags)];
986
987 /* Copy the default cpu flags. */
988 memcpy (flags, cpu_flags, sizeof (cpu_flags));
989
ad9de929 990 if (flag[0] == '~')
8a9036a4
L
991 {
992 last = flag + strlen (flag);
993
994 if (flag[1] == '(')
995 {
996 last -= 1;
997 next = flag + 2;
998 if (*last != ')')
a6743a54 999 fail (_("%s: %d: missing `)' in bitfield: %s\n"), filename,
8a9036a4
L
1000 lineno, flag);
1001 *last = '\0';
1002 }
1003 else
1004 next = flag + 1;
1005
13ed231a
JB
1006 /* First we turn on everything except for cpu64, cpuno64, and - if
1007 present - the padding field. */
40fb9820 1008 for (i = 0; i < ARRAY_SIZE (flags); i++)
13ed231a 1009 if (flags[i].position < Cpu64)
40fb9820 1010 flags[i].value = 1;
8a9036a4
L
1011
1012 /* Turn off selective bits. */
ad9de929 1013 value = 0;
40fb9820 1014 }
ad9de929
JB
1015
1016 if (strcmp (flag, "0"))
40fb9820 1017 {
ad9de929 1018 /* Turn on/off selective bits. */
40fb9820 1019 last = flag + strlen (flag);
ad9de929 1020 for (; next && next < last; )
40fb9820 1021 {
c587b3f9 1022 str = next_field (next, '|', &next, last);
40fb9820 1023 if (str)
ad9de929 1024 set_bitfield (str, flags, value, ARRAY_SIZE (flags), lineno);
40fb9820
L
1025 }
1026 }
1027
1028 output_cpu_flags (table, flags, ARRAY_SIZE (flags), macro,
1029 comma, indent);
1030}
1031
1032static void
1033output_opcode_modifier (FILE *table, bitfield *modifier, unsigned int size)
1034{
1035 unsigned int i;
1036
1037 fprintf (table, " { ");
1038
1039 for (i = 0; i < size - 1; i++)
1040 {
10632b79
L
1041 if (((i + 1) % 20) != 0)
1042 fprintf (table, "%d, ", modifier[i].value);
1043 else
1044 fprintf (table, "%d,", modifier[i].value);
40fb9820
L
1045 if (((i + 1) % 20) == 0)
1046 fprintf (table, "\n ");
1047 }
1048
1049 fprintf (table, "%d },\n", modifier[i].value);
1050}
1051
73d214b2 1052/* Returns LOG2 of element size. */
4a1b91ea 1053static int
73d214b2 1054get_element_size (char **opnd, int lineno)
4a1b91ea
L
1055{
1056 char *str, *next, *last, *op;
73d214b2
JB
1057 const char *full = opnd[0];
1058 int elem_size = INT_MAX;
4a1b91ea 1059
73d214b2
JB
1060 /* Find the memory operand. */
1061 while (full != NULL && strstr(full, "BaseIndex") == NULL)
1062 full = *++opnd;
1063 if (full == NULL)
1064 fail (_("%s: %d: no memory operand\n"), filename, lineno);
4a1b91ea 1065
73d214b2 1066 op = xstrdup (full);
4a1b91ea
L
1067 last = op + strlen (op);
1068 for (next = op; next && next < last; )
1069 {
1070 str = next_field (next, '|', &next, last);
1071 if (str)
1072 {
1073 if (strcasecmp(str, "Byte") == 0)
1074 {
73d214b2 1075 /* The smallest element size, no need to check
4a1b91ea 1076 further. */
73d214b2 1077 elem_size = 0;
4a1b91ea
L
1078 break;
1079 }
1080 else if (strcasecmp(str, "Word") == 0)
1081 {
73d214b2
JB
1082 if (elem_size > 1)
1083 elem_size = 1;
4a1b91ea
L
1084 }
1085 else if (strcasecmp(str, "Dword") == 0)
1086 {
73d214b2
JB
1087 if (elem_size > 2)
1088 elem_size = 2;
4a1b91ea
L
1089 }
1090 else if (strcasecmp(str, "Qword") == 0)
1091 {
73d214b2
JB
1092 if (elem_size > 3)
1093 elem_size = 3;
4a1b91ea
L
1094 }
1095 }
1096 }
1097 free (op);
1098
73d214b2
JB
1099 if (elem_size == INT_MAX)
1100 fail (_("%s: %d: unknown element size: %s\n"), filename, lineno, full);
4a1b91ea 1101
73d214b2 1102 return elem_size;
4a1b91ea
L
1103}
1104
35648716 1105static void
389d00a5
JB
1106process_i386_opcode_modifier (FILE *table, char *mod, unsigned int space,
1107 unsigned int prefix, char **opnd, int lineno)
40fb9820
L
1108{
1109 char *str, *next, *last;
1110 bitfield modifiers [ARRAY_SIZE (opcode_modifiers)];
1111
7ac20022
JB
1112 active_isstring = 0;
1113
40fb9820
L
1114 /* Copy the default opcode modifier. */
1115 memcpy (modifiers, opcode_modifiers, sizeof (modifiers));
1116
1117 if (strcmp (mod, "0"))
1118 {
507916b8
JB
1119 unsigned int have_w = 0, bwlq_suf = 0xf;
1120
40fb9820
L
1121 last = mod + strlen (mod);
1122 for (next = mod; next && next < last; )
1123 {
c587b3f9 1124 str = next_field (next, '|', &next, last);
40fb9820 1125 if (str)
7ac20022 1126 {
4a1b91ea
L
1127 int val = 1;
1128 if (strcasecmp(str, "Broadcast") == 0)
73d214b2
JB
1129 val = get_element_size (opnd, lineno) + BYTE_BROADCAST;
1130 else if (strcasecmp(str, "Disp8MemShift") == 0)
1131 val = get_element_size (opnd, lineno);
8b65b895 1132
4a1b91ea 1133 set_bitfield (str, modifiers, val, ARRAY_SIZE (modifiers),
8b65b895 1134 lineno);
7ac20022
JB
1135 if (strcasecmp(str, "IsString") == 0)
1136 active_isstring = 1;
507916b8
JB
1137
1138 if (strcasecmp(str, "W") == 0)
1139 have_w = 1;
1140
1141 if (strcasecmp(str, "No_bSuf") == 0)
1142 bwlq_suf &= ~1;
1143 if (strcasecmp(str, "No_wSuf") == 0)
1144 bwlq_suf &= ~2;
1145 if (strcasecmp(str, "No_lSuf") == 0)
1146 bwlq_suf &= ~4;
1147 if (strcasecmp(str, "No_qSuf") == 0)
1148 bwlq_suf &= ~8;
7ac20022 1149 }
40fb9820 1150 }
507916b8 1151
389d00a5
JB
1152 if (space)
1153 {
1154 if (!modifiers[OpcodeSpace].value)
1155 modifiers[OpcodeSpace].value = space;
1156 else if (modifiers[OpcodeSpace].value != space)
1157 fail (_("%s:%d: Conflicting opcode space specifications\n"),
1158 filename, lineno);
1159 else
1160 fprintf (stderr,
1161 _("%s:%d: Warning: redundant opcode space specification\n"),
1162 filename, lineno);
1163 }
1164
35648716
JB
1165 if (prefix)
1166 {
1167 if (!modifiers[OpcodePrefix].value)
1168 modifiers[OpcodePrefix].value = prefix;
1169 else if (modifiers[OpcodePrefix].value != prefix)
1170 fail (_("%s:%d: Conflicting prefix specifications\n"),
1171 filename, lineno);
1172 else
1173 fprintf (stderr,
1174 _("%s:%d: Warning: redundant prefix specification\n"),
1175 filename, lineno);
1176 }
1177
507916b8
JB
1178 if (have_w && !bwlq_suf)
1179 fail ("%s: %d: stray W modifier\n", filename, lineno);
1180 if (have_w && !(bwlq_suf & 1))
1181 fprintf (stderr, "%s: %d: W modifier without Byte operand(s)\n",
1182 filename, lineno);
1183 if (have_w && !(bwlq_suf & ~1))
1184 fprintf (stderr,
1185 "%s: %d: W modifier without Word/Dword/Qword operand(s)\n",
1186 filename, lineno);
40fb9820
L
1187 }
1188 output_opcode_modifier (table, modifiers, ARRAY_SIZE (modifiers));
1189}
1190
7ac20022
JB
1191enum stage {
1192 stage_macros,
1193 stage_opcodes,
1194 stage_registers,
1195};
1196
40fb9820 1197static void
bab6aec1 1198output_operand_type (FILE *table, enum operand_class class,
75e5731b 1199 enum operand_instance instance,
bab6aec1 1200 const bitfield *types, unsigned int size,
7ac20022 1201 enum stage stage, const char *indent)
40fb9820
L
1202{
1203 unsigned int i;
1204
75e5731b 1205 fprintf (table, "{ { %d, %d, ", class, instance);
40fb9820
L
1206
1207 for (i = 0; i < size - 1; i++)
1208 {
75e5731b 1209 if (((i + 3) % 20) != 0)
10632b79
L
1210 fprintf (table, "%d, ", types[i].value);
1211 else
1212 fprintf (table, "%d,", types[i].value);
75e5731b 1213 if (((i + 3) % 20) == 0)
40fb9820
L
1214 {
1215 /* We need \\ for macro. */
7ac20022 1216 if (stage == stage_macros)
10632b79 1217 fprintf (table, " \\\n%s", indent);
40fb9820
L
1218 else
1219 fprintf (table, "\n%s", indent);
1220 }
1221 }
1222
1223 fprintf (table, "%d } }", types[i].value);
1224}
1225
1226static void
7ac20022 1227process_i386_operand_type (FILE *table, char *op, enum stage stage,
bd5295b2 1228 const char *indent, int lineno)
40fb9820
L
1229{
1230 char *str, *next, *last;
bab6aec1 1231 enum operand_class class = ClassNone;
75e5731b 1232 enum operand_instance instance = InstanceNone;
40fb9820
L
1233 bitfield types [ARRAY_SIZE (operand_types)];
1234
1235 /* Copy the default operand type. */
1236 memcpy (types, operand_types, sizeof (types));
1237
1238 if (strcmp (op, "0"))
1239 {
7ac20022
JB
1240 int baseindex = 0;
1241
40fb9820
L
1242 last = op + strlen (op);
1243 for (next = op; next && next < last; )
1244 {
c587b3f9 1245 str = next_field (next, '|', &next, last);
bab6aec1
JB
1246 if (str)
1247 {
1248 unsigned int i;
1249
1250 if (!strncmp(str, "Class=", 6))
1251 {
1252 for (i = 0; i < ARRAY_SIZE(operand_classes); ++i)
1253 if (!strcmp(str + 6, operand_classes[i].name))
1254 {
1255 class = operand_classes[i].value;
1256 str = NULL;
1257 break;
1258 }
1259 }
75e5731b
JB
1260
1261 if (str && !strncmp(str, "Instance=", 9))
1262 {
1263 for (i = 0; i < ARRAY_SIZE(operand_instances); ++i)
1264 if (!strcmp(str + 9, operand_instances[i].name))
1265 {
1266 instance = operand_instances[i].value;
1267 str = NULL;
1268 break;
1269 }
1270 }
bab6aec1 1271 }
40fb9820 1272 if (str)
7ac20022
JB
1273 {
1274 set_bitfield (str, types, 1, ARRAY_SIZE (types), lineno);
1275 if (strcasecmp(str, "BaseIndex") == 0)
1276 baseindex = 1;
1277 }
1278 }
1279
1280 if (stage == stage_opcodes && baseindex && !active_isstring)
1281 {
1282 set_bitfield("Disp8", types, 1, ARRAY_SIZE (types), lineno);
1283 if (!active_cpu_flags.bitfield.cpu64
1284 && !active_cpu_flags.bitfield.cpumpx)
1285 set_bitfield("Disp16", types, 1, ARRAY_SIZE (types), lineno);
a775efc8 1286 set_bitfield("Disp32", types, 1, ARRAY_SIZE (types), lineno);
40fb9820
L
1287 }
1288 }
75e5731b
JB
1289 output_operand_type (table, class, instance, types, ARRAY_SIZE (types),
1290 stage, indent);
40fb9820
L
1291}
1292
c587b3f9
L
1293static void
1294output_i386_opcode (FILE *table, const char *name, char *str,
bd5295b2 1295 char *last, int lineno)
c587b3f9 1296{
389d00a5 1297 unsigned int i, length, prefix = 0, space = 0;
9a182d04 1298 char *base_opcode, *extension_opcode, *end;
c587b3f9 1299 char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS];
73e45eb2 1300 unsigned long long opcode;
c587b3f9 1301
c587b3f9
L
1302 /* Find base_opcode. */
1303 base_opcode = next_field (str, ',', &str, last);
1304
68993386
JB
1305 /* Find extension_opcode, if any. */
1306 extension_opcode = strchr (base_opcode, '/');
1307 if (extension_opcode)
1308 *extension_opcode++ = '\0';
c587b3f9 1309
c587b3f9
L
1310 /* Find cpu_flags. */
1311 cpu_flags = next_field (str, ',', &str, last);
1312
1313 /* Find opcode_modifier. */
1314 opcode_modifier = next_field (str, ',', &str, last);
1315
1316 /* Remove the first {. */
1317 str = remove_leading_whitespaces (str);
1318 if (*str != '{')
1319 abort ();
1320 str = remove_leading_whitespaces (str + 1);
75363b6d 1321 remove_trailing_whitespaces (str);
c587b3f9 1322
75363b6d 1323 /* Remove } and trailing white space. */
c587b3f9 1324 i = strlen (str);
75363b6d 1325 if (!i || str[i - 1] != '}')
c587b3f9 1326 abort ();
75363b6d
JB
1327 str[--i] = '\0';
1328 remove_trailing_whitespaces (str);
c587b3f9 1329
75363b6d
JB
1330 if (!*str)
1331 operand_types [i = 0] = NULL;
1332 else
c587b3f9 1333 {
75363b6d 1334 last = str + strlen (str);
c587b3f9 1335
75363b6d
JB
1336 /* Find operand_types. */
1337 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
c587b3f9 1338 {
75363b6d
JB
1339 if (str >= last)
1340 {
1341 operand_types [i] = NULL;
1342 break;
1343 }
c587b3f9 1344
75363b6d 1345 operand_types [i] = next_field (str, ',', &str, last);
c587b3f9
L
1346 }
1347 }
1348
73e45eb2 1349 opcode = strtoull (base_opcode, &end, 0);
c587b3f9 1350
9a182d04 1351 /* Determine opcode length. */
73e45eb2 1352 for (length = 1; length < 8; ++length)
9a182d04
JB
1353 if (!(opcode >> (8 * length)))
1354 break;
1355
35648716
JB
1356 /* Transform prefixes encoded in the opcode into opcode modifier
1357 representation. */
9a182d04 1358 if (length > 1)
8b65b895 1359 {
9a182d04 1360 switch (opcode >> (8 * length - 8))
8b65b895 1361 {
35648716
JB
1362 case 0x66: prefix = PREFIX_0X66; break;
1363 case 0xF3: prefix = PREFIX_0XF3; break;
1364 case 0xF2: prefix = PREFIX_0XF2; break;
8b65b895 1365 }
35648716 1366
9a182d04 1367 if (prefix)
73e45eb2 1368 opcode &= (1ULL << (8 * --length)) - 1;
8b65b895 1369 }
c587b3f9 1370
389d00a5
JB
1371 /* Transform opcode space encoded in the opcode into opcode modifier
1372 representation. */
1373 if (length > 1 && (opcode >> (8 * length - 8)) == 0xf)
1374 {
1375 switch ((opcode >> (8 * length - 16)) & 0xff)
1376 {
1377 default: space = SPACE_0F; break;
1378 case 0x38: space = SPACE_0F38; break;
1379 case 0x3A: space = SPACE_0F3A; break;
1380 }
1381
1382 if (space != SPACE_0F && --length == 1)
1383 fail (_("%s:%d: %s: unrecognized opcode encoding space\n"),
1384 filename, lineno, name);
73e45eb2 1385 opcode &= (1ULL << (8 * --length)) - 1;
389d00a5
JB
1386 }
1387
73e45eb2
JB
1388 if (length > 2)
1389 fail (_("%s:%d: %s: residual opcode (0x%0*llx) too large\n"),
1390 filename, lineno, name, 2 * length, opcode);
1391
37cea588 1392 fprintf (table, " { \"%s\", 0x%0*llx%s, %lu, %s,\n",
68993386
JB
1393 name, 2 * (int)length, opcode, end, i,
1394 extension_opcode ? extension_opcode : "None");
35648716 1395
389d00a5 1396 process_i386_opcode_modifier (table, opcode_modifier, space, prefix,
35648716
JB
1397 operand_types, lineno);
1398
dac10fb0
JB
1399 process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno);
1400
c587b3f9
L
1401 fprintf (table, " { ");
1402
1403 for (i = 0; i < ARRAY_SIZE (operand_types); i++)
1404 {
75363b6d 1405 if (!operand_types[i])
c587b3f9
L
1406 {
1407 if (i == 0)
7ac20022
JB
1408 process_i386_operand_type (table, "0", stage_opcodes, "\t ",
1409 lineno);
c587b3f9
L
1410 break;
1411 }
1412
1413 if (i != 0)
1414 fprintf (table, ",\n ");
1415
7ac20022 1416 process_i386_operand_type (table, operand_types[i], stage_opcodes,
bd5295b2 1417 "\t ", lineno);
c587b3f9
L
1418 }
1419 fprintf (table, " } },\n");
1420}
1421
1422struct opcode_hash_entry
1423{
1424 struct opcode_hash_entry *next;
1425 char *name;
1426 char *opcode;
bd5295b2 1427 int lineno;
c587b3f9
L
1428};
1429
1430/* Calculate the hash value of an opcode hash entry P. */
1431
1432static hashval_t
1433opcode_hash_hash (const void *p)
1434{
1435 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1436 return htab_hash_string (entry->name);
1437}
1438
1439/* Compare a string Q against an opcode hash entry P. */
1440
1441static int
1442opcode_hash_eq (const void *p, const void *q)
1443{
1444 struct opcode_hash_entry *entry = (struct opcode_hash_entry *) p;
1445 const char *name = (const char *) q;
1446 return strcmp (name, entry->name) == 0;
1447}
1448
4c4898e8
JB
1449static void
1450parse_template (char *buf, int lineno)
1451{
1452 char sep, *end, *name;
e07ae9a3 1453 struct template *tmpl;
4c4898e8
JB
1454 struct template_instance *last_inst = NULL;
1455
1456 buf = remove_leading_whitespaces (buf + 1);
1457 end = strchr (buf, ':');
1458 if (end == NULL)
e07ae9a3
JB
1459 {
1460 struct template *prev = NULL;
1461
1462 end = strchr (buf, '>');
1463 if (end == NULL)
1464 fail ("%s: %d: missing ':' or '>'\n", filename, lineno);
1465 if (*remove_leading_whitespaces (end + 1))
1466 fail ("%s: %d: malformed template purge\n", filename, lineno);
1467 *end = '\0';
1468 remove_trailing_whitespaces (buf);
1469 /* Don't bother freeing the various structures. */
1470 for (tmpl = templates; tmpl != NULL; tmpl = (prev = tmpl)->next)
1471 if (!strcmp (buf, tmpl->name))
1472 break;
1473 if (tmpl == NULL)
1474 fail ("%s: %d: no template '%s'\n", filename, lineno, buf);
1475 if (prev)
1476 prev->next = tmpl->next;
1477 else
1478 templates = tmpl->next;
1479 return;
1480 }
4c4898e8
JB
1481 *end++ = '\0';
1482 remove_trailing_whitespaces (buf);
1483
1484 if (*buf == '\0')
1485 fail ("%s: %d: missing template identifier\n", filename, lineno);
e07ae9a3 1486 tmpl = xmalloc (sizeof (*tmpl));
4c4898e8
JB
1487 tmpl->name = xstrdup (buf);
1488
1489 tmpl->params = NULL;
1490 do {
1491 struct template_param *param;
1492
1493 buf = remove_leading_whitespaces (end);
1494 end = strpbrk (buf, ":,");
1495 if (end == NULL)
1496 fail ("%s: %d: missing ':' or ','\n", filename, lineno);
1497
1498 sep = *end;
1499 *end++ = '\0';
1500 remove_trailing_whitespaces (buf);
1501
1502 param = xmalloc (sizeof (*param));
1503 param->name = xstrdup (buf);
1504 param->next = tmpl->params;
1505 tmpl->params = param;
1506 } while (sep == ':');
1507
1508 tmpl->instances = NULL;
1509 do {
1510 struct template_instance *inst;
1511 char *cur, *next;
1512 const struct template_param *param;
1513
1514 buf = remove_leading_whitespaces (end);
1515 end = strpbrk (buf, ",>");
1516 if (end == NULL)
1517 fail ("%s: %d: missing ',' or '>'\n", filename, lineno);
1518
1519 sep = *end;
1520 *end++ = '\0';
1521
1522 inst = xmalloc (sizeof (*inst));
c3ffb8f3
AM
1523 inst->next = NULL;
1524 inst->args = NULL;
4c4898e8
JB
1525
1526 cur = next_field (buf, ':', &next, end);
5cdaf100 1527 inst->name = *cur != '$' ? xstrdup (cur) : "";
4c4898e8
JB
1528
1529 for (param = tmpl->params; param; param = param->next)
1530 {
1531 struct template_arg *arg = xmalloc (sizeof (*arg));
1532
1533 cur = next_field (next, ':', &next, end);
1534 if (next > end)
1535 fail ("%s: %d: missing argument for '%s'\n", filename, lineno, param->name);
1536 arg->val = xstrdup (cur);
1537 arg->next = inst->args;
1538 inst->args = arg;
1539 }
1540
1541 if (tmpl->instances)
1542 last_inst->next = inst;
1543 else
1544 tmpl->instances = inst;
1545 last_inst = inst;
1546 } while (sep == ',');
1547
1548 buf = remove_leading_whitespaces (end);
1549 if (*buf)
1550 fprintf(stderr, "%s: %d: excess characters '%s'\n",
1551 filename, lineno, buf);
1552
1553 tmpl->next = templates;
1554 templates = tmpl;
1555}
1556
1557static unsigned int
1558expand_templates (char *name, const char *str, htab_t opcode_hash_table,
1559 struct opcode_hash_entry ***opcode_array_p, int lineno)
1560{
1561 static unsigned int idx, opcode_array_size;
1562 struct opcode_hash_entry **opcode_array = *opcode_array_p;
1563 struct opcode_hash_entry **hash_slot, **entry;
1564 char *ptr1 = strchr(name, '<'), *ptr2;
1565
1566 if (ptr1 == NULL)
1567 {
1568 /* Get the slot in hash table. */
1569 hash_slot = (struct opcode_hash_entry **)
1570 htab_find_slot_with_hash (opcode_hash_table, name,
1571 htab_hash_string (name),
1572 INSERT);
1573
1574 if (*hash_slot == NULL)
1575 {
1576 /* It is the new one. Put it on opcode array. */
1577 if (idx >= opcode_array_size)
1578 {
1579 /* Grow the opcode array when needed. */
1580 opcode_array_size += 1024;
1581 opcode_array = (struct opcode_hash_entry **)
1582 xrealloc (opcode_array,
1583 sizeof (*opcode_array) * opcode_array_size);
1584 *opcode_array_p = opcode_array;
1585 }
1586
1587 opcode_array[idx] = (struct opcode_hash_entry *)
1588 xmalloc (sizeof (struct opcode_hash_entry));
1589 opcode_array[idx]->next = NULL;
1590 opcode_array[idx]->name = xstrdup (name);
1591 opcode_array[idx]->opcode = xstrdup (str);
1592 opcode_array[idx]->lineno = lineno;
1593 *hash_slot = opcode_array[idx];
1594 idx++;
1595 }
1596 else
1597 {
1598 /* Append it to the existing one. */
1599 entry = hash_slot;
1600 while ((*entry) != NULL)
1601 entry = &(*entry)->next;
1602 *entry = (struct opcode_hash_entry *)
1603 xmalloc (sizeof (struct opcode_hash_entry));
1604 (*entry)->next = NULL;
1605 (*entry)->name = (*hash_slot)->name;
1606 (*entry)->opcode = xstrdup (str);
1607 (*entry)->lineno = lineno;
1608 }
1609 }
1610 else if ((ptr2 = strchr(ptr1 + 1, '>')) == NULL)
1611 fail ("%s: %d: missing '>'\n", filename, lineno);
1612 else
1613 {
1614 const struct template *tmpl;
1615 const struct template_instance *inst;
1616
1617 *ptr1 = '\0';
1618 ptr1 = remove_leading_whitespaces (ptr1 + 1);
1619 remove_trailing_whitespaces (ptr1);
1620
1621 *ptr2++ = '\0';
1622
1623 for ( tmpl = templates; tmpl; tmpl = tmpl->next )
1624 if (!strcmp(ptr1, tmpl->name))
1625 break;
1626 if (!tmpl)
1627 fail ("reference to unknown template '%s'\n", ptr1);
1628
1629 for (inst = tmpl->instances; inst; inst = inst->next)
1630 {
1631 char *name2 = xmalloc(strlen(name) + strlen(inst->name) + strlen(ptr2) + 1);
1632 char *str2 = xmalloc(2 * strlen(str));
1633 const char *src;
1634
1635 strcpy (name2, name);
1636 strcat (name2, inst->name);
1637 strcat (name2, ptr2);
1638
1639 for (ptr1 = str2, src = str; *src; )
1640 {
1641 const char *ident = tmpl->name, *end;
1642 const struct template_param *param;
1643 const struct template_arg *arg;
1644
1645 if ((*ptr1 = *src++) != '<')
1646 {
1647 ++ptr1;
1648 continue;
1649 }
1650 while (ISSPACE(*src))
1651 ++src;
1652 while (*ident && *src == *ident)
1653 ++src, ++ident;
1654 while (ISSPACE(*src))
1655 ++src;
1656 if (*src != ':' || *ident != '\0')
1657 {
1658 memcpy (++ptr1, tmpl->name, ident - tmpl->name);
1659 ptr1 += ident - tmpl->name;
1660 continue;
1661 }
1662 while (ISSPACE(*++src))
1663 ;
1664
1665 end = src;
1666 while (*end != '\0' && !ISSPACE(*end) && *end != '>')
1667 ++end;
1668
1669 for (param = tmpl->params, arg = inst->args; param;
1670 param = param->next, arg = arg->next)
1671 {
1672 if (end - src == strlen (param->name)
1673 && !memcmp (src, param->name, end - src))
1674 {
1675 src = end;
1676 break;
1677 }
1678 }
1679
1680 if (param == NULL)
1681 fail ("template '%s' has no parameter '%.*s'\n",
1682 tmpl->name, (int)(end - src), src);
1683
1684 while (ISSPACE(*src))
1685 ++src;
1686 if (*src != '>')
1687 fail ("%s: %d: missing '>'\n", filename, lineno);
1688
1689 memcpy(ptr1, arg->val, strlen(arg->val));
1690 ptr1 += strlen(arg->val);
1691 ++src;
1692 }
1693
1694 *ptr1 = '\0';
1695
1696 expand_templates (name2, str2, opcode_hash_table, opcode_array_p,
1697 lineno);
1698
1699 free (str2);
1700 free (name2);
1701 }
1702 }
1703
1704 return idx;
1705}
1706
40b8e679 1707static void
72ffa0fb 1708process_i386_opcodes (FILE *table)
40b8e679 1709{
3d4d5afa 1710 FILE *fp;
40b8e679 1711 char buf[2048];
65f440c8 1712 unsigned int i, j, nr;
c587b3f9 1713 char *str, *p, *last, *name;
c587b3f9 1714 htab_t opcode_hash_table;
4c4898e8 1715 struct opcode_hash_entry **opcode_array = NULL;
c30be56e 1716 int lineno = 0, marker = 0;
40b8e679 1717
3d4d5afa 1718 filename = "i386-opc.tbl";
c30be56e 1719 fp = stdin;
40b8e679 1720
c587b3f9 1721 i = 0;
c587b3f9
L
1722 opcode_hash_table = htab_create_alloc (16, opcode_hash_hash,
1723 opcode_hash_eq, NULL,
1724 xcalloc, free);
1725
34edb9ad 1726 fprintf (table, "\n/* i386 opcode table. */\n\n");
99f0fb12 1727 fprintf (table, "static const insn_template i386_optab[] =\n{\n");
40b8e679 1728
c587b3f9 1729 /* Put everything on opcode array. */
40b8e679
L
1730 while (!feof (fp))
1731 {
1732 if (fgets (buf, sizeof (buf), fp) == NULL)
1733 break;
1734
1735 p = remove_leading_whitespaces (buf);
1736
33b6a20a
JB
1737 for ( ; ; )
1738 {
1739 lineno++;
1740
1741 /* Skip comments. */
1742 str = strstr (p, "//");
1743 if (str != NULL)
1744 {
1745 str[0] = '\0';
1746 remove_trailing_whitespaces (p);
1747 break;
1748 }
40b8e679 1749
33b6a20a
JB
1750 /* Look for line continuation character. */
1751 remove_trailing_whitespaces (p);
1752 j = strlen (buf);
1753 if (!j || buf[j - 1] != '+')
1754 break;
1755 if (j >= sizeof (buf) - 1)
1756 fail (_("%s: %d: (continued) line too long\n"), filename, lineno);
1757
1758 if (fgets (buf + j - 1, sizeof (buf) - j + 1, fp) == NULL)
1759 {
1760 fprintf (stderr, "%s: Line continuation on last line?\n",
1761 filename);
1762 break;
1763 }
1764 }
40b8e679
L
1765
1766 switch (p[0])
1767 {
1768 case '#':
c30be56e
JB
1769 if (!strcmp("### MARKER ###", buf))
1770 marker = 1;
1771 else
1772 {
1773 /* Since we ignore all included files (we only care about their
1774 #define-s here), we don't need to monitor filenames. The final
1775 line number directive is going to refer to the main source file
1776 again. */
1777 char *end;
1778 unsigned long ln;
1779
1780 p = remove_leading_whitespaces (p + 1);
1781 if (!strncmp(p, "line", 4))
1782 p += 4;
1783 ln = strtoul (p, &end, 10);
1784 if (ln > 1 && ln < INT_MAX
1785 && *remove_leading_whitespaces (end) == '"')
1786 lineno = ln - 1;
1787 }
c587b3f9 1788 /* Ignore comments. */
40b8e679
L
1789 case '\0':
1790 continue;
1791 break;
4c4898e8
JB
1792 case '<':
1793 parse_template (p, lineno);
1794 continue;
40b8e679 1795 default:
c30be56e
JB
1796 if (!marker)
1797 continue;
40b8e679
L
1798 break;
1799 }
1800
1801 last = p + strlen (p);
1802
1803 /* Find name. */
c587b3f9 1804 name = next_field (p, ',', &str, last);
40b8e679 1805
4c4898e8
JB
1806 i = expand_templates (name, str, opcode_hash_table, &opcode_array,
1807 lineno);
c587b3f9 1808 }
40b8e679 1809
c587b3f9
L
1810 /* Process opcode array. */
1811 for (j = 0; j < i; j++)
1812 {
4c4898e8
JB
1813 struct opcode_hash_entry *next;
1814
c587b3f9
L
1815 for (next = opcode_array[j]; next; next = next->next)
1816 {
1817 name = next->name;
1818 str = next->opcode;
bd5295b2 1819 lineno = next->lineno;
c587b3f9 1820 last = str + strlen (str);
bd5295b2 1821 output_i386_opcode (table, name, str, last, lineno);
40b8e679 1822 }
40b8e679
L
1823 }
1824
34edb9ad
L
1825 fclose (fp);
1826
34edb9ad 1827 fprintf (table, "};\n");
65f440c8
JB
1828
1829 /* Generate opcode sets array. */
1830 fprintf (table, "\n/* i386 opcode sets table. */\n\n");
1831 fprintf (table, "static const insn_template *const i386_op_sets[] =\n{\n");
1832 fprintf (table, " i386_optab,\n");
1833
1834 for (nr = j = 0; j < i; j++)
1835 {
1836 struct opcode_hash_entry *next = opcode_array[j];
1837
1838 do
1839 {
1840 ++nr;
1841 next = next->next;
1842 }
1843 while (next);
1844 fprintf (table, " i386_optab + %u,\n", nr);
1845 }
1846
1847 fprintf (table, "};\n");
40b8e679
L
1848}
1849
1850static void
72ffa0fb 1851process_i386_registers (FILE *table)
40b8e679 1852{
3d4d5afa 1853 FILE *fp;
40b8e679
L
1854 char buf[2048];
1855 char *str, *p, *last;
1856 char *reg_name, *reg_type, *reg_flags, *reg_num;
a60de03c 1857 char *dw2_32_num, *dw2_64_num;
bd5295b2 1858 int lineno = 0;
40b8e679 1859
3d4d5afa
L
1860 filename = "i386-reg.tbl";
1861 fp = fopen (filename, "r");
40b8e679 1862 if (fp == NULL)
34edb9ad 1863 fail (_("can't find i386-reg.tbl for reading, errno = %s\n"),
40fb9820 1864 xstrerror (errno));
40b8e679 1865
34edb9ad 1866 fprintf (table, "\n/* i386 register table. */\n\n");
99f0fb12 1867 fprintf (table, "static const reg_entry i386_regtab[] =\n{\n");
40b8e679
L
1868
1869 while (!feof (fp))
1870 {
1871 if (fgets (buf, sizeof (buf), fp) == NULL)
1872 break;
1873
3d4d5afa
L
1874 lineno++;
1875
40b8e679
L
1876 p = remove_leading_whitespaces (buf);
1877
1878 /* Skip comments. */
1879 str = strstr (p, "//");
1880 if (str != NULL)
1881 str[0] = '\0';
1882
1883 /* Remove trailing white spaces. */
1884 remove_trailing_whitespaces (p);
1885
1886 switch (p[0])
1887 {
1888 case '#':
34edb9ad 1889 fprintf (table, "%s\n", p);
40b8e679
L
1890 case '\0':
1891 continue;
1892 break;
1893 default:
1894 break;
1895 }
1896
1897 last = p + strlen (p);
1898
1899 /* Find reg_name. */
c587b3f9 1900 reg_name = next_field (p, ',', &str, last);
40b8e679
L
1901
1902 /* Find reg_type. */
c587b3f9 1903 reg_type = next_field (str, ',', &str, last);
40b8e679
L
1904
1905 /* Find reg_flags. */
c587b3f9 1906 reg_flags = next_field (str, ',', &str, last);
40b8e679
L
1907
1908 /* Find reg_num. */
c587b3f9 1909 reg_num = next_field (str, ',', &str, last);
a60de03c 1910
40fb9820
L
1911 fprintf (table, " { \"%s\",\n ", reg_name);
1912
7ac20022
JB
1913 process_i386_operand_type (table, reg_type, stage_registers, "\t",
1914 lineno);
40fb9820 1915
a60de03c 1916 /* Find 32-bit Dwarf2 register number. */
c587b3f9 1917 dw2_32_num = next_field (str, ',', &str, last);
a60de03c
JB
1918
1919 /* Find 64-bit Dwarf2 register number. */
c587b3f9 1920 dw2_64_num = next_field (str, ',', &str, last);
a60de03c
JB
1921
1922 fprintf (table, ",\n %s, %s, { %s, %s } },\n",
1923 reg_flags, reg_num, dw2_32_num, dw2_64_num);
40b8e679
L
1924 }
1925
34edb9ad
L
1926 fclose (fp);
1927
1928 fprintf (table, "};\n");
40b8e679 1929
99f0fb12 1930 fprintf (table, "\nstatic const unsigned int i386_regtab_size = ARRAY_SIZE (i386_regtab);\n");
40b8e679
L
1931}
1932
40fb9820
L
1933static void
1934process_i386_initializers (void)
1935{
1936 unsigned int i;
1937 FILE *fp = fopen ("i386-init.h", "w");
1938 char *init;
1939
1940 if (fp == NULL)
1941 fail (_("can't create i386-init.h, errno = %s\n"),
1942 xstrerror (errno));
1943
1944 process_copyright (fp);
1945
1946 for (i = 0; i < ARRAY_SIZE (cpu_flag_init); i++)
1947 {
1948 fprintf (fp, "\n#define %s \\\n", cpu_flag_init[i].name);
1949 init = xstrdup (cpu_flag_init[i].init);
bd5295b2 1950 process_i386_cpu_flag (fp, init, 1, "", " ", -1);
40fb9820
L
1951 free (init);
1952 }
1953
40fb9820
L
1954 fprintf (fp, "\n");
1955
1956 fclose (fp);
1957}
1958
40b8e679
L
1959/* Program options. */
1960#define OPTION_SRCDIR 200
1961
29c048b6 1962struct option long_options[] =
40b8e679
L
1963{
1964 {"srcdir", required_argument, NULL, OPTION_SRCDIR},
1965 {"debug", no_argument, NULL, 'd'},
1966 {"version", no_argument, NULL, 'V'},
1967 {"help", no_argument, NULL, 'h'},
1968 {0, no_argument, NULL, 0}
1969};
1970
1971static void
1972print_version (void)
1973{
1974 printf ("%s: version 1.0\n", program_name);
1975 xexit (0);
1976}
1977
1978static void
1979usage (FILE * stream, int status)
1980{
1981 fprintf (stream, "Usage: %s [-V | --version] [-d | --debug] [--srcdir=dirname] [--help]\n",
1982 program_name);
1983 xexit (status);
1984}
1985
1986int
1987main (int argc, char **argv)
1988{
1989 extern int chdir (char *);
1990 char *srcdir = NULL;
8b40d594 1991 int c;
e92bae62 1992 unsigned int i, cpumax;
72ffa0fb 1993 FILE *table;
29c048b6 1994
40b8e679
L
1995 program_name = *argv;
1996 xmalloc_set_program_name (program_name);
1997
1998 while ((c = getopt_long (argc, argv, "vVdh", long_options, 0)) != EOF)
1999 switch (c)
2000 {
2001 case OPTION_SRCDIR:
2002 srcdir = optarg;
2003 break;
2004 case 'V':
2005 case 'v':
2006 print_version ();
2007 break;
2008 case 'd':
2009 debug = 1;
2010 break;
2011 case 'h':
2012 case '?':
2013 usage (stderr, 0);
2014 default:
2015 case 0:
2016 break;
2017 }
2018
2019 if (optind != argc)
2020 usage (stdout, 1);
2021
29c048b6 2022 if (srcdir != NULL)
40b8e679
L
2023 if (chdir (srcdir) != 0)
2024 fail (_("unable to change directory to \"%s\", errno = %s\n"),
40fb9820
L
2025 srcdir, xstrerror (errno));
2026
e92bae62
L
2027 /* cpu_flags isn't sorted by position. */
2028 cpumax = 0;
2029 for (i = 0; i < ARRAY_SIZE (cpu_flags); i++)
2030 if (cpu_flags[i].position > cpumax)
2031 cpumax = cpu_flags[i].position;
2032
40fb9820 2033 /* Check the unused bitfield in i386_cpu_flags. */
e89c5eaa 2034#ifdef CpuUnused
1d942ae9
JB
2035 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 2);
2036
e92bae62
L
2037 if ((cpumax - 1) != CpuMax)
2038 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 2039#else
1d942ae9
JB
2040 static_assert (ARRAY_SIZE (cpu_flags) == CpuMax + 1);
2041
e92bae62
L
2042 if (cpumax != CpuMax)
2043 fail (_("CpuMax != %d!\n"), cpumax);
e89c5eaa 2044
8b40d594
L
2045 c = CpuNumOfBits - CpuMax - 1;
2046 if (c)
2047 fail (_("%d unused bits in i386_cpu_flags.\n"), c);
40fb9820
L
2048#endif
2049
1d942ae9
JB
2050 static_assert (ARRAY_SIZE (opcode_modifiers) == Opcode_Modifier_Num);
2051
40fb9820 2052 /* Check the unused bitfield in i386_operand_type. */
1d942ae9 2053#ifdef OTUnused
75e5731b
JB
2054 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2055 == OTNum + 1);
1d942ae9 2056#else
75e5731b
JB
2057 static_assert (ARRAY_SIZE (operand_types) + CLASS_WIDTH + INSTANCE_WIDTH
2058 == OTNum);
1d942ae9 2059
51c8edf6 2060 c = OTNumOfBits - OTNum;
8b40d594
L
2061 if (c)
2062 fail (_("%d unused bits in i386_operand_type.\n"), c);
40fb9820
L
2063#endif
2064
2065 qsort (cpu_flags, ARRAY_SIZE (cpu_flags), sizeof (cpu_flags [0]),
2066 compare);
2067
2068 qsort (opcode_modifiers, ARRAY_SIZE (opcode_modifiers),
2069 sizeof (opcode_modifiers [0]), compare);
2070
2071 qsort (operand_types, ARRAY_SIZE (operand_types),
2072 sizeof (operand_types [0]), compare);
40b8e679 2073
34edb9ad
L
2074 table = fopen ("i386-tbl.h", "w");
2075 if (table == NULL)
40fb9820
L
2076 fail (_("can't create i386-tbl.h, errno = %s\n"),
2077 xstrerror (errno));
34edb9ad 2078
72ffa0fb 2079 process_copyright (table);
40b8e679 2080
72ffa0fb
L
2081 process_i386_opcodes (table);
2082 process_i386_registers (table);
40fb9820 2083 process_i386_initializers ();
40b8e679 2084
34edb9ad
L
2085 fclose (table);
2086
40b8e679
L
2087 exit (0);
2088}