static void output_i386_opcode (FILE *table, const char *name, char *str, char *last, int lineno) { unsigned int i; char *operands, *base_opcode, *extension_opcode, *opcode_length; char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS]; /* Find number of operands. */ operands = next_field (str, ',', &str, last); /* Find base_opcode. */ base_opcode = next_field (str, ',', &str, last); /* Find extension_opcode. */ extension_opcode = next_field (str, ',', &str, last); /* Find opcode_length. */ opcode_length = next_field (str, ',', &str, last); /* Find cpu_flags. */ cpu_flags = next_field (str, ',', &str, last); /* Find opcode_modifier. */ opcode_modifier = next_field (str, ',', &str, last); /* Remove the first {. */ str = remove_leading_whitespaces (str); if (*str != '{') abort (); str = remove_leading_whitespaces (str + 1); i = strlen (str); /* There are at least "X}". */ if (i < 2) abort (); /* Remove trailing white spaces and }. */ do { i--; if (ISSPACE (str[i]) || str[i] == '}') str[i] = '\0'; else break; } while (i != 0); last = str + i; /* Find operand_types. */ for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (str >= last) { operand_types [i] = NULL; break; } operand_types [i] = next_field (str, ',', &str, last); if (*operand_types[i] == '0') { if (i != 0) operand_types[i] = NULL; break; } } fprintf (table, " { \"%s\", %s, %s, %s, %s,\n", name, operands, base_opcode, extension_opcode, opcode_length); process_i386_cpu_flag (table, cpu_flags, 0, ",", " ", lineno); process_i386_opcode_modifier (table, opcode_modifier, lineno); fprintf (table, " { "); for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (operand_types[i] == NULL || *operand_types[i] == '0') { if (i == 0) process_i386_operand_type (table, "0", 0, "\t ", lineno); break; } if (i != 0) fprintf (table, ",\n "); process_i386_operand_type (table, operand_types[i], 0, "\t ", lineno); } fprintf (table, " } },\n"); }
static void process_i386_opcodes (FILE *table) { FILE *fp; char buf[2048]; unsigned int i, j; char *str, *p, *last, *name; struct opcode_hash_entry **hash_slot, **entry, *next; htab_t opcode_hash_table; struct opcode_hash_entry **opcode_array; unsigned int opcode_array_size = 1024; int lineno = 0; filename = "i386-opc.tbl"; fp = fopen (filename, "r"); if (fp == NULL) fail (_("can't find i386-opc.tbl for reading, errno = %s\n"), xstrerror (errno)); i = 0; opcode_array = (struct opcode_hash_entry **) xmalloc (sizeof (*opcode_array) * opcode_array_size); opcode_hash_table = htab_create_alloc (16, opcode_hash_hash, opcode_hash_eq, NULL, xcalloc, free); fprintf (table, "\n/* i386 opcode table. */\n\n"); fprintf (table, "const insn_template i386_optab[] =\n{\n"); /* Put everything on opcode array. */ while (!feof (fp)) { if (fgets (buf, sizeof (buf), fp) == NULL) break; lineno++; p = remove_leading_whitespaces (buf); /* Skip comments. */ str = strstr (p, "//"); if (str != NULL) str[0] = '\0'; /* Remove trailing white spaces. */ remove_trailing_whitespaces (p); switch (p[0]) { case '#': /* Ignore comments. */ case '\0': continue; break; default: break; } last = p + strlen (p); /* Find name. */ name = next_field (p, ',', &str, last); /* Get the slot in hash table. */ hash_slot = (struct opcode_hash_entry **) htab_find_slot_with_hash (opcode_hash_table, name, htab_hash_string (name), INSERT); if (*hash_slot == NULL) { /* It is the new one. Put it on opcode array. */ if (i >= opcode_array_size) { /* Grow the opcode array when needed. */ opcode_array_size += 1024; opcode_array = (struct opcode_hash_entry **) xrealloc (opcode_array, sizeof (*opcode_array) * opcode_array_size); } opcode_array[i] = (struct opcode_hash_entry *) xmalloc (sizeof (struct opcode_hash_entry)); opcode_array[i]->next = NULL; opcode_array[i]->name = xstrdup (name); opcode_array[i]->opcode = xstrdup (str); opcode_array[i]->lineno = lineno; *hash_slot = opcode_array[i]; i++; } else { /* Append it to the existing one. */ entry = hash_slot; while ((*entry) != NULL) entry = &(*entry)->next; *entry = (struct opcode_hash_entry *) xmalloc (sizeof (struct opcode_hash_entry)); (*entry)->next = NULL; (*entry)->name = (*hash_slot)->name; (*entry)->opcode = xstrdup (str); (*entry)->lineno = lineno; } } /* Process opcode array. */ for (j = 0; j < i; j++) { for (next = opcode_array[j]; next; next = next->next) { name = next->name; str = next->opcode; lineno = next->lineno; last = str + strlen (str); output_i386_opcode (table, name, str, last, lineno); } } fclose (fp); fprintf (table, " { NULL, 0, 0, 0, 0,\n"); process_i386_cpu_flag (table, "0", 0, ",", " ", -1); process_i386_opcode_modifier (table, "0", -1); fprintf (table, " { "); process_i386_operand_type (table, "0", 0, "\t ", -1); fprintf (table, " } }\n"); fprintf (table, "};\n"); }
static void process_i386_opcodes (FILE *table) { FILE *fp; char buf[2048]; unsigned int i; char *str, *p, *last; char *name, *operands, *base_opcode, *extension_opcode; char *opcode_length; char *cpu_flags, *opcode_modifier, *operand_types [MAX_OPERANDS]; filename = "i386-opc.tbl"; fp = fopen (filename, "r"); if (fp == NULL) fail (_("can't find i386-opc.tbl for reading, errno = %s\n"), xstrerror (errno)); fprintf (table, "\n/* i386 opcode table. */\n\n"); fprintf (table, "const template i386_optab[] =\n{\n"); while (!feof (fp)) { if (fgets (buf, sizeof (buf), fp) == NULL) break; lineno++; p = remove_leading_whitespaces (buf); /* Skip comments. */ str = strstr (p, "//"); if (str != NULL) str[0] = '\0'; /* Remove trailing white spaces. */ remove_trailing_whitespaces (p); switch (p[0]) { case '#': fprintf (table, "%s\n", p); case '\0': continue; break; default: break; } last = p + strlen (p); /* Find name. */ name = next_field (p, ',', &str); if (str >= last) abort (); /* Find number of operands. */ operands = next_field (str, ',', &str); if (str >= last) abort (); /* Find base_opcode. */ base_opcode = next_field (str, ',', &str); if (str >= last) abort (); /* Find extension_opcode. */ extension_opcode = next_field (str, ',', &str); if (str >= last) abort (); /* Find opcode_length. */ opcode_length = next_field (str, ',', &str); if (str >= last) abort (); /* Find cpu_flags. */ cpu_flags = next_field (str, ',', &str); if (str >= last) abort (); /* Find opcode_modifier. */ opcode_modifier = next_field (str, ',', &str); if (str >= last) abort (); /* Remove the first {. */ str = remove_leading_whitespaces (str); if (*str != '{') abort (); str = remove_leading_whitespaces (str + 1); i = strlen (str); /* There are at least "X}". */ if (i < 2) abort (); /* Remove trailing white spaces and }. */ do { i--; if (ISSPACE (str[i]) || str[i] == '}') str[i] = '\0'; else break; } while (i != 0); last = str + i; /* Find operand_types. */ for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (str >= last) { operand_types [i] = NULL; break; } operand_types [i] = next_field (str, ',', &str); if (*operand_types[i] == '0') { if (i != 0) operand_types[i] = NULL; break; } } fprintf (table, " { \"%s\", %s, %s, %s, %s,\n", name, operands, base_opcode, extension_opcode, opcode_length); process_i386_cpu_flag (table, cpu_flags, 0, ",", " "); process_i386_opcode_modifier (table, opcode_modifier); fprintf (table, " { "); for (i = 0; i < ARRAY_SIZE (operand_types); i++) { if (operand_types[i] == NULL || *operand_types[i] == '0') { if (i == 0) process_i386_operand_type (table, "0", 0, "\t "); break; } if (i != 0) fprintf (table, ",\n "); process_i386_operand_type (table, operand_types[i], 0, "\t "); } fprintf (table, " } },\n"); } fclose (fp); fprintf (table, " { NULL, 0, 0, 0, 0,\n"); process_i386_cpu_flag (table, "0", 0, ",", " "); process_i386_opcode_modifier (table, "0"); fprintf (table, " { "); process_i386_operand_type (table, "0", 0, "\t "); fprintf (table, " } }\n"); fprintf (table, "};\n"); }