diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/d2c/coder.c | 419 | ||||
-rw-r--r-- | tools/d2c/coder.h | 12 | ||||
-rw-r--r-- | tools/d2c/d2c.c | 18 | ||||
-rw-r--r-- | tools/d2c/d2c.mk | 21 | ||||
-rw-r--r-- | tools/d2c/encoding.c | 218 | ||||
-rw-r--r-- | tools/d2c/encoding.h | 14 | ||||
-rw-r--r-- | tools/d2c/grammar.y | 50 | ||||
-rw-r--r-- | tools/d2c/hooks/manager.c | 78 | ||||
-rw-r--r-- | tools/d2c/hooks/manager.h | 6 | ||||
-rw-r--r-- | tools/d2c/syntax.c | 33 | ||||
-rw-r--r-- | tools/d2c/syntax.h | 6 | ||||
-rw-r--r-- | tools/d2c/tokens.l | 2 |
12 files changed, 753 insertions, 124 deletions
diff --git a/tools/d2c/coder.c b/tools/d2c/coder.c index 9977d22..eff35c2 100644 --- a/tools/d2c/coder.c +++ b/tools/d2c/coder.c @@ -116,9 +116,15 @@ static bool output_coder_format(const rented_coder *, const output_info *, const /* Initialise le contenu utile du fichier des identifiants. */ static void init_coder_identifiers_file(int, const output_info *); +/* Initialise le contenu utile du fichier des sous-identifiants. */ +static void init_coder_sub_identifiers_file(int, const output_info *); + /* Initialise le contenu utile du fichier des mots clefs. */ static void init_coder_keywords_file(int, const output_info *); +/* Initialise le contenu utile du fichier des décrochages. */ +static void init_coder_hooks_file(int, const output_info *); + /* Initialise le contenu utile du fichier des descriptions. */ static void init_coder_descriptions_file(int, const output_info *); @@ -1044,6 +1050,7 @@ bool output_coder_body(const rented_coder *coder, const output_info *info) break; case IOT_FORMAT: + assert(j == 0); assert(enc_name->dest == NULL); result = output_coder_format(coder, info, enc_name, coder->specs[j], header_fd, code_fd); break; @@ -1146,6 +1153,7 @@ static bool output_coder_raw(const rented_coder *coder, const output_info *info, coding_bits *bits; /* Gestionnaire de bits */ unsigned int wide; /* Taille des mots */ size_t maxlen; /* Taille à compléter */ + char *fullname; /* Désignation complète */ arch = strdup(info->arch_cn); make_string_lower(arch); @@ -1214,7 +1222,13 @@ static bool output_coder_raw(const rented_coder *coder, const output_info *info, dprintf(cfd, "{"); dprintf(cfd, "\n"); - result = write_encoding_spec_raw_disass(encoding, cfd, arch, coder->id, coder->pp); + make_string_upper(name); + + asprintf(&fullname, "%s_%s", info->id_prefix, name); + + result = write_encoding_spec_raw_disass(encoding, cfd, arch, fullname, coder->pp); + + free(fullname); dprintf(cfd, "}\n"); dprintf(cfd, "\n"); @@ -1397,6 +1411,7 @@ static bool output_coder_format(const rented_coder *coder, const output_info *in char *arch; /* Architecture à traiter */ char *name; /* Désignation à manipuler */ size_t maxlen; /* Taille à compléter */ + char *fullname; /* Désignation complète */ arch = strdup(info->arch_cn); make_string_lower(arch); @@ -1457,7 +1472,13 @@ static bool output_coder_format(const rented_coder *coder, const output_info *in dprintf(cfd, "{"); dprintf(cfd, "\n"); - result = write_encoding_spec_format_disass(encoding, cfd, arch, coder->id, info->fmt_prefix); + make_string_upper(name); + + asprintf(&fullname, "%s_%s", info->id_prefix, name); + + result = write_encoding_spec_format_disass(encoding, cfd, arch, fullname, info->fmt_prefix); + + free(fullname); dprintf(cfd, "}\n"); dprintf(cfd, "\n"); @@ -1679,6 +1700,142 @@ bool fini_coder_identifiers_file(const char *pathname, const output_info *info) * Paramètres : fd = flux ouvert en écriture mis à disposition. * * info = précisions quant à la génération. * * * +* Description : Initialise le contenu utile du fichier des sous-identifiants.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void init_coder_sub_identifiers_file(int fd, const output_info *info) +{ + dprintf(fd, "#ifndef _%s_SUBIDENTIFIERS_H\n", info->guard); + dprintf(fd, "#define _%s_SUBIDENTIFIERS_H\n", info->guard); + + dprintf(fd, "\n"); + dprintf(fd, "\n"); + + dprintf(fd, "/* Enumération de tous les opcodes */\n"); + dprintf(fd, "typedef enum _%sSyntax\n", info->arch_cn); + dprintf(fd, "{\n"); + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* info = précisions quant à la génération. * +* * +* Description : Génère ou complète un fichier créant les sous-identifiants. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool output_coder_sub_identifier(const rented_coder *coder, const output_info *info) +{ + bool result; /* Bilan à retourner */ + bool created; /* Note une création */ + int fd; /* Flux ouvert en écriture */ + char *name; /* Désignation à manipuler */ + char *fullname; /* Désignation complète */ + size_t i; /* Boucle de parcours */ + + result = false; + + /* Ouverture de la destination */ + + fd = open_global_header_file(coder, info, "subidentifiers", &created); + if (fd == -1) goto ocsi_exit; + + if (created) + { + write_header_file_license(fd, info, "subidentifiers", "définition des sous-identifiants uniques pour"); + init_coder_sub_identifiers_file(fd, info); + } + + /* Impression des sous-identifiants */ + + name = get_coder_code_name(coder); + make_string_upper(name); + + asprintf(&fullname, "%s_%s", info->id_prefix, name); + + free(name); + + result = true; + + for (i = 0; i < coder->specs_count && result; i++) + result = write_encoding_spec_subid(coder->specs[i], fd, fullname); + + free(fullname); + + result = true; + + ocsi_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pathname = chemin d'accès au fichier à traiter. * +* info = précisions quant à la génération. * +* * +* Description : Finalise le contenu utile du fichier des sous-identifiants. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool fini_coder_sub_identifiers_file(const char *pathname, const output_info *info) +{ + bool result; /* Bilan à retourner */ + int fd; /* Flux ouvert en écriture */ + + result = false; + + fd = open(pathname, O_WRONLY | O_APPEND, 0644); + if (fd == -1) + { + perror("open()"); + goto fcif_exit; + } + + dprintf(fd, "\n"); + dprintf(fd, " %s_ENC_COUNT\n", info->id_prefix); + dprintf(fd, "\n"); + + dprintf(fd, "} %sSyntax;\n", info->arch_cn); + + dprintf(fd, "\n"); + dprintf(fd, "\n"); + dprintf(fd, "\n"); + + dprintf(fd, "#endif /* _%s_SUBIDENTIFIERS_H */\n", info->guard); + + result = true; + + fcif_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : fd = flux ouvert en écriture mis à disposition. * +* info = précisions quant à la génération. * +* * * Description : Initialise le contenu utile du fichier des mots clefs. * * * * Retour : - * @@ -1696,7 +1853,23 @@ static void init_coder_keywords_file(int fd, const output_info *info) dprintf(fd, "\n"); dprintf(fd, "\n"); - dprintf(fd, "#include \"identifiers.h\"\n"); + + switch (info->type) + { + case IOT_UNDEFINED: + assert(false); + break; + + case IOT_RAW: + dprintf(fd, "#include \"subidentifiers.h\"\n"); + break; + + case IOT_FORMAT: + dprintf(fd, "#include \"identifiers.h\"\n"); + break; + + } + dprintf(fd, "\n"); dprintf(fd, "\n"); dprintf(fd, "\n"); @@ -1705,7 +1878,8 @@ static void init_coder_keywords_file(int fd, const output_info *info) make_string_lower(larch); dprintf(fd, "/* Enumération de tous les mots clefs */\n"); - dprintf(fd, "static char *_%s_keywords[%s_COUNT] = {\n", larch, info->id_prefix); + dprintf(fd, "static char *_%s_keywords[%s_%sCOUNT] = {\n", + larch, info->id_prefix, info->type == IOT_RAW ? "ENC_" : ""); dprintf(fd, "\n"); free(larch); @@ -1732,6 +1906,8 @@ bool output_coder_keyword(const rented_coder *coder, const output_info *info) bool created; /* Note une création */ int fd; /* Flux ouvert en écriture */ char *name; /* Désignation à manipuler */ + char *fullname; /* Désignation complète */ + size_t i; /* Boucle de parcours */ result = false; @@ -1754,24 +1930,49 @@ bool output_coder_keyword(const rented_coder *coder, const output_info *info) init_coder_keywords_file(fd, info); } - /* Impression de la colonne */ + /* Lancement des impressions */ name = get_coder_code_name(coder); make_string_upper(name); - dprintf(fd, "\t[%s_%s] = ", info->id_prefix, name); + asprintf(&fullname, "%s_%s", info->id_prefix, name); free(name); - /* Impression du mot clef */ + result = true; - name = get_coder_nominal_name(coder); + for (i = 0; i < coder->specs_count && result; i++) + switch (info->type) + { + case IOT_UNDEFINED: + assert(false); + result = false; + break; - dprintf(fd, "\"%s\",\n", name); + case IOT_RAW: + result = write_encoding_spec_keywords(coder->specs[i], fd, fullname); + break; - free(name); + case IOT_FORMAT: + assert(i == 0); - result = true; + /* Impression de la colonne */ + + dprintf(fd, "\t[%s] = ", fullname); + + /* Impression du mot clef */ + + name = get_coder_nominal_name(coder); + + dprintf(fd, "\"%s\",\n", name); + + free(name); + + break; + + } + + free(fullname); ock_exit: @@ -1830,6 +2031,194 @@ bool fini_coder_keywords_file(const char *pathname, const output_info *info) * Paramètres : fd = flux ouvert en écriture mis à disposition. * * info = précisions quant à la génération. * * * +* Description : Initialise le contenu utile du fichier des décrochages. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void init_coder_hooks_file(int fd, const output_info *info) +{ + char *larch; /* Architecture en minuscules */ + + dprintf(fd, "#ifndef _%s_HOOKS_H\n", info->guard); + dprintf(fd, "#define _%s_HOOKS_H\n", info->guard); + + dprintf(fd, "\n"); + dprintf(fd, "\n"); + + switch (info->type) + { + case IOT_UNDEFINED: + assert(false); + break; + + case IOT_RAW: + dprintf(fd, "#include \"subidentifiers.h\"\n"); + break; + + case IOT_FORMAT: + dprintf(fd, "#include \"identifiers.h\"\n"); + break; + + } + + dprintf(fd, "\n"); + dprintf(fd, "\n"); + + dprintf(fd, "##INCLUDES##\n"); + + dprintf(fd, "\n"); + dprintf(fd, "\n"); + dprintf(fd, "\n"); + + larch = strdup(info->arch_cn); + make_string_lower(larch); + + dprintf(fd, "/* Définitions des décrochages pour l'établissement d'instructions */\n"); + dprintf(fd, "static const instr_hook_fc _%s_hooks[%s_%sCOUNT][IPH_COUNT] = {\n", + larch, info->id_prefix, info->type == IOT_RAW ? "ENC_" : ""); + dprintf(fd, "\n"); + + free(larch); + +} + + +/****************************************************************************** +* * +* Paramètres : coder = gestion par la machine en remplacement de l'humain. * +* info = précisions quant à la génération. * +* * +* Description : Génère ou complète un fichier constituant les décrochages. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool output_coder_hooks(const rented_coder *coder, const output_info *info) +{ + bool result; /* Bilan à retourner */ + bool created; /* Note une création */ + int fd; /* Flux ouvert en écriture */ + char *name; /* Désignation à manipuler */ + char *fullname; /* Désignation complète */ + size_t i; /* Boucle de parcours */ + + result = false; + + /* S'il n'y a pas lieu de traiter l'instruction */ + + if (coder->useless) + { + result = true; + goto och_exit; + } + + /* Ouverture de la destination */ + + fd = open_global_header_file(coder, info, "hooks", &created); + if (fd == -1) goto och_exit; + + if (created) + { + write_header_file_license(fd, info, "hooks", "définition des décrochages pour instructions"); + init_coder_hooks_file(fd, info); + } + + /* Lancement des impressions */ + + name = get_coder_code_name(coder); + make_string_upper(name); + + asprintf(&fullname, "%s_%s", info->id_prefix, name); + + free(name); + + result = true; + + for (i = 0; i < coder->specs_count && result; i++) + switch (info->type) + { + case IOT_UNDEFINED: + assert(false); + result = false; + break; + + case IOT_RAW: + result = write_encoding_spec_hooks(coder->specs[i], fd, fullname, true); + break; + + case IOT_FORMAT: + assert(i == 0); + result = write_encoding_spec_hooks(coder->specs[i], fd, fullname, false); + break; + + } + + free(fullname); + + och_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : pathname = chemin d'accès au fichier à traiter. * +* info = précisions quant à la génération. * +* * +* Description : Finalise le contenu utile du fichier des décrochages. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool fini_coder_hooks_file(const char *pathname, const output_info *info) +{ + bool result; /* Bilan à retourner */ + int fd; /* Flux ouvert en écriture */ + + result = false; + + fd = open(pathname, O_WRONLY | O_APPEND, 0644); + if (fd == -1) + { + perror("open()"); + goto fchf_exit; + } + + dprintf(fd, "\n"); + dprintf(fd, "};\n"); + + dprintf(fd, "\n"); + dprintf(fd, "\n"); + dprintf(fd, "\n"); + + dprintf(fd, "#endif /* _%s_HOOKS_H */\n", info->guard); + + result = true; + + fchf_exit: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : fd = flux ouvert en écriture mis à disposition. * +* info = précisions quant à la génération. * +* * * Description : Initialise le contenu utile du fichier des descriptions. * * * * Retour : - * @@ -1847,7 +2236,9 @@ static void init_coder_descriptions_file(int fd, const output_info *info) dprintf(fd, "\n"); dprintf(fd, "\n"); + dprintf(fd, "#include \"identifiers.h\"\n"); + dprintf(fd, "\n"); dprintf(fd, "\n"); dprintf(fd, "\n"); @@ -1891,13 +2282,13 @@ bool output_coder_description(const rented_coder *coder, const output_info *info if (coder->useless) { result = true; - goto ock_exit; + goto ocd_exit; } /* Ouverture de la destination */ fd = open_global_header_file(coder, info, "descriptions", &created); - if (fd == -1) goto ock_exit; + if (fd == -1) goto ocd_exit; if (created) { @@ -1928,7 +2319,7 @@ bool output_coder_description(const rented_coder *coder, const output_info *info result = true; - ock_exit: + ocd_exit: return result; diff --git a/tools/d2c/coder.h b/tools/d2c/coder.h index a3fc81f..34544c2 100644 --- a/tools/d2c/coder.h +++ b/tools/d2c/coder.h @@ -147,12 +147,24 @@ bool output_coder_identifier(const rented_coder *, const output_info *); /* Finalise le contenu utile du fichier des identifiants. */ bool fini_coder_identifiers_file(const char *, const output_info *); +/* Génère ou complète un fichier créant les sous-identifiants. */ +bool output_coder_sub_identifier(const rented_coder *, const output_info *); + +/* Finalise le contenu utile du fichier des sous-identifiants. */ +bool fini_coder_sub_identifiers_file(const char *, const output_info *); + /* Génère ou complète un fichier constituant les mots clefs. */ bool output_coder_keyword(const rented_coder *, const output_info *); /* Finalise le contenu utile du fichier des mots clefs. */ bool fini_coder_keywords_file(const char *, const output_info *); +/* Génère ou complète un fichier constituant les décrochages. */ +bool output_coder_hooks(const rented_coder *, const output_info *); + +/* Finalise le contenu utile du fichier des décrochages. */ +bool fini_coder_hooks_file(const char *, const output_info *); + /* Génère ou complète un fichier constituant les descriptions. */ bool output_coder_description(const rented_coder *, const output_info *); diff --git a/tools/d2c/d2c.c b/tools/d2c/d2c.c index ee28af4..1d9b5b6 100644 --- a/tools/d2c/d2c.c +++ b/tools/d2c/d2c.c @@ -287,12 +287,18 @@ int main(int argc, char **argv) status = output_coder_identifier(coder, &info); if (!status) goto clean_exit; - if (info.type == IOT_FORMAT) + if (info.type == IOT_RAW) { - status = output_coder_keyword(coder, &info); + status = output_coder_sub_identifier(coder, &info); if (!status) goto clean_exit; } + status = output_coder_keyword(coder, &info); + if (!status) goto clean_exit; + + status = output_coder_hooks(coder, &info); + if (!status) goto clean_exit; + status = output_coder_description(coder, &info); if (!status) goto clean_exit; @@ -316,9 +322,15 @@ int main(int argc, char **argv) else if (strcmp(base, "identifiers.h") == 0) status = fini_coder_identifiers_file(argv[optind], &info); - else if (info.type == IOT_FORMAT && strcmp(base, "keywords.h") == 0) + else if (strcmp(base, "subidentifiers.h") == 0 && info.type == IOT_RAW) + status = fini_coder_sub_identifiers_file(argv[optind], &info); + + else if (strcmp(base, "keywords.h") == 0) status = fini_coder_keywords_file(argv[optind], &info); + else if (strcmp(base, "hooks.h") == 0) + status = fini_coder_hooks_file(argv[optind], &info); + else if (strcmp(base, "descriptions.h") == 0) status = fini_coder_descriptions_file(argv[optind], &info); diff --git a/tools/d2c/d2c.mk b/tools/d2c/d2c.mk index 10bd226..c889fd4 100644 --- a/tools/d2c/d2c.mk +++ b/tools/d2c/d2c.mk @@ -29,6 +29,7 @@ fix_verbose_0 = echo " FIX " `basename $$f`; # FIXED_C_INCLUDES = # FIXED_H_INCLUDES = +# FIXED_H_HOOKS_INCLUDES = SUFFIXES = .g @@ -51,17 +52,21 @@ finish_headers: done fix_includes_in_c_templates: - @for f in `find $(D2C_OUTDIR) -type f -name '*.c'`; do \ - if grep -q '##INCLUDES##' $$f; then \ - $(fix_verbose)sed -i 's@##INCLUDES##@$(FIXED_C_INCLUDES)@' $$f; \ - fi; \ + @for f in `find $(D2C_OUTDIR) -type f -name '*.c'`; do \ + if grep -q '##INCLUDES##' $$f; then \ + $(fix_verbose)sed -i 's@##INCLUDES##@$(FIXED_C_INCLUDES)@' $$f; \ + fi; \ done fix_includes_in_h_templates: - @for f in `find $(D2C_OUTDIR) -type f -name '*.h'`; do \ - if grep -q '##INCLUDES##' $$f; then \ - $(fix_verbose)sed -i 's@##INCLUDES##@$(FIXED_H_INCLUDES)@' $$f ; \ - fi; \ + @for f in `find $(D2C_OUTDIR) -type f -name '*.h'`; do \ + if grep -q '##INCLUDES##' $$f; then \ + if [ `basename $$f` == "hooks.h" ]; then \ + $(fix_verbose)sed -i 's@##INCLUDES##@$(FIXED_H_HOOKS_INCLUDES)@' $$f ; \ + else \ + $(fix_verbose)sed -i 's@##INCLUDES##@$(FIXED_H_INCLUDES)@' $$f ; \ + fi; \ + fi; \ done # Merci http://www.commandlinefu.com/commands/view/10276/grep-tab-t diff --git a/tools/d2c/encoding.c b/tools/d2c/encoding.c index 95dca46..9ed4663 100644 --- a/tools/d2c/encoding.c +++ b/tools/d2c/encoding.c @@ -188,6 +188,8 @@ char *build_encoding_spec_prefix(const encoding_spec *spec) { char *result; /* Chaîne à retourner */ + assert(spec->lprefix); + asprintf(&result, "%s%u", spec->lprefix, spec->index); return result; @@ -308,7 +310,7 @@ encoding_syntax *get_current_encoding_syntax(const encoding_spec *spec) * Paramètres : spec = spécification servant de base à l'opération. * * fd = descripteur d'un flux ouvert en écriture. * * arch = architecture visée par l'opération. * -* id = identifiant unique attribué à l'instruction. * +* id = désignation de l'identifiant d'instruction. * * pp = pré-processeur pour les échanges de chaînes. * * * * Description : Traduit en code une sous-fonction de désassemblage. * @@ -319,11 +321,13 @@ encoding_syntax *get_current_encoding_syntax(const encoding_spec *spec) * * ******************************************************************************/ -bool write_encoding_spec_raw_disass(const encoding_spec *spec, int fd, const char *arch, const instr_id *id, const pre_processor *pp) +bool write_encoding_spec_raw_disass(const encoding_spec *spec, int fd, const char *arch, const char *id, const pre_processor *pp) { bool result; /* Bilan à retourner */ bool openbar; /* Syntaxe unique par défaut ? */ disass_assert *dassert; /* Eventuelles conditions */ + char *suffix; /* Complément d'identifiant */ + char *sid; /* Base de sous-identifiant */ size_t i; /* Boucle de parcours */ bool op_decl; /* Suivi des déclaration #1 */ bool imm_decl; /* Suivi des déclaration #2 */ @@ -384,9 +388,6 @@ bool write_encoding_spec_raw_disass(const encoding_spec *spec, int fd, const cha dprintf(fd, "\n"); - result = declare_hook_functions(spec->hooks, fd); - if (!result) goto wesrd_exit; - /* Vérification que le décodage est possible */ result &= check_bits_correctness(spec->bits, fd); @@ -407,8 +408,17 @@ bool write_encoding_spec_raw_disass(const encoding_spec *spec, int fd, const cha result = define_used_bits_fields(spec->bits, fd); if (!result) goto wesrd_exit; + suffix = build_encoding_spec_prefix(spec); + make_string_upper(suffix); + + asprintf(&sid, "%s_%s", id, suffix); + + free(suffix); + for (i = 0; i < spec->syntax_count && result; i++) - result = write_encoding_syntax(spec->syntaxes[i], fd, arch, spec->bits, openbar, &bad_exit); + result = write_encoding_syntax(spec->syntaxes[i], fd, arch, spec->bits, openbar, id, sid, i, &bad_exit); + + free(sid); if (!result) goto wesrd_exit; @@ -430,11 +440,6 @@ bool write_encoding_spec_raw_disass(const encoding_spec *spec, int fd, const cha dprintf(fd, "\n"); - /* Inscriptions des éventuelles fonctions ou propriété à lier */ - - result = write_hook_functions(spec->hooks, fd); - if (!result) goto wesrd_exit; - /* Conclusion globale */ dprintf(fd, "\treturn result;\n"); @@ -476,10 +481,9 @@ bool write_encoding_spec_raw_disass(const encoding_spec *spec, int fd, const cha * * ******************************************************************************/ -bool write_encoding_spec_format_disass(const encoding_spec *spec, int fd, const char *arch, const instr_id *id, const char *prefix) +bool write_encoding_spec_format_disass(const encoding_spec *spec, int fd, const char *arch, const char *id, const char *prefix) { bool result; /* Bilan à retourner */ - unsigned int iid; /* Identifiant unique attribué */ bool bad_exit; /* Ajout d'une sortie d'échec ?*/ conv_list *conversions; /* Conversions de la syntaxe */ decoding_rules *rules; /* Règles de la syntaxe */ @@ -491,22 +495,12 @@ bool write_encoding_spec_format_disass(const encoding_spec *spec, int fd, const dprintf(fd, "\n"); - result = declare_hook_functions(spec->hooks, fd); - if (!result) goto wesfd_exit; - /* Création de l'instruction en elle-même */ - iid = get_instruction_id_value(id); - - dprintf(fd, "\tresult = g_%s_instruction_new(0x%x);\n", arch, iid); + dprintf(fd, "\tresult = g_%s_instruction_new(%s);\n", arch, id); dprintf(fd, "\n"); - /* Inscriptions des éventuelles fonctions ou propriété à lier */ - - result = write_hook_functions(spec->hooks, fd); - if (!result) goto wesfd_exit; - bad_exit = false; assert(spec->syntax_count <= 1); @@ -558,3 +552,179 @@ bool write_encoding_spec_format_disass(const encoding_spec *spec, int fd, const return result; } + + +/****************************************************************************** +* * +* Paramètres : spec = spécification servant de base à l'opération. * +* fd = descripteur d'un flux ouvert en écriture. * +* name = désignation de l'identifiant d'instruction. * +* * +* Description : Imprime les mots clefs de chaque syntaxe. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_encoding_spec_keywords(const encoding_spec *spec, int fd, const char *name) +{ + bool result; /* Bilan à retourner */ + char *suffix; /* Complément d'identifiant */ + size_t i; /* Boucle de parcours */ + asm_pattern *pattern; /* Définition d'assemblage */ + const char *keyword; /* Mot clef principal */ + + result = true; + + suffix = build_encoding_spec_prefix(spec); + make_string_upper(suffix); + + for (i = 0; i < spec->syntax_count; i++) + { + /* Impression de la colonne */ + + if (spec->syntax_count == 1) + dprintf(fd, "\t[%s_%s]", name, suffix); + else + dprintf(fd, "\t[%s_%s_%zu]", name, suffix, i); + + /* Impression des décrochages */ + + pattern = get_asm_pattern_in_encoding_syntax(spec->syntaxes[i]); + + keyword = get_keyword_from_asm_pattern(pattern); + + dprintf(fd, " = \"%s\",\n", keyword); + + } + + free(suffix); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : spec = spécification servant de base à l'opération. * +* fd = descripteur d'un flux ouvert en écriture. * +* name = désignation de l'identifiant d'instruction. * +* * +* Description : Imprime la définition d'un sous-identifiant pour un encodage.* +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_encoding_spec_subid(const encoding_spec *spec, int fd, const char *name) +{ + bool result; /* Bilan à retourner */ + char *suffix; /* Complément d'identifiant */ + size_t i; /* Boucle de parcours */ + instr_id *subid; /* Sous-identifiant de syntaxe */ + unsigned int idval; /* Identifiant unique attribué */ + + result = true; + + suffix = build_encoding_spec_prefix(spec); + make_string_upper(suffix); + + for (i = 0; i < spec->syntax_count; i++) + { + subid = get_encoding_syntax_subid(spec->syntaxes[i]); + idval = get_instruction_id_value(subid); + + if (spec->syntax_count == 1) + dprintf(fd, "\t%s_%s = %u,\n", name, suffix, idval); + else + dprintf(fd, "\t%s_%s_%zu = %u,\n", name, suffix, i, idval); + + } + + free(suffix); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : spec = spécification servant de base à l'opération. * +* fd = descripteur d'un flux ouvert en écriture. * +* name = désignation de l'identifiant d'instruction. * +* refine = utilisation d'un identifiant plus précis ? * +* * +* Description : Imprime d'éventuels décrochages spécifiés pour un encodage. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool write_encoding_spec_hooks(const encoding_spec *spec, int fd, const char *name, bool refine) +{ + bool result; /* Bilan à retourner */ + char *suffix; /* Complément d'identifiant */ + size_t i; /* Boucle de parcours */ + + if (!has_hook_functions(spec->hooks)) + result = true; + + else + { + if (refine) + { + suffix = build_encoding_spec_prefix(spec); + make_string_upper(suffix); + + for (i = 0; i < spec->syntax_count; i++) + { + /* Impression de la colonne */ + + if (spec->syntax_count == 1) + dprintf(fd, "\t[%s_%s]", name, suffix); + else + dprintf(fd, "\t[%s_%s_%zu]", name, suffix, i); + + /* Impression des décrochages */ + + dprintf(fd, " = {\n", name); + + result = write_hook_functions(spec->hooks, fd); + + dprintf(fd, "\t},\n", name); + + } + + free(suffix); + + } + + else + { + /* Impression de la colonne */ + + dprintf(fd, "\t[%s]", name); + + /* Impression des décrochages */ + + dprintf(fd, " = {\n", name); + + result = write_hook_functions(spec->hooks, fd); + + dprintf(fd, "\t},\n", name); + + } + + } + + return result; + +} diff --git a/tools/d2c/encoding.h b/tools/d2c/encoding.h index 5e5eb14..cd93b95 100644 --- a/tools/d2c/encoding.h +++ b/tools/d2c/encoding.h @@ -33,7 +33,6 @@ #include "bits/manager.h" #include "format/manager.h" #include "hooks/manager.h" -#include "id/manager.h" @@ -72,10 +71,19 @@ void push_new_encoding_syntax(encoding_spec *); encoding_syntax *get_current_encoding_syntax(const encoding_spec *); /* Traduit en code une sous-fonction de désassemblage. */ -bool write_encoding_spec_raw_disass(const encoding_spec *, int, const char *, const instr_id *, const pre_processor *); +bool write_encoding_spec_raw_disass(const encoding_spec *, int, const char *, const char *, const pre_processor *); /* Traduit en code une sous-fonction de désassemblage. */ -bool write_encoding_spec_format_disass(const encoding_spec *, int, const char *, const instr_id *, const char *); +bool write_encoding_spec_format_disass(const encoding_spec *, int, const char *, const char *, const char *); + +/* Imprime les mots clefs de chaque syntaxe. */ +bool write_encoding_spec_keywords(const encoding_spec *, int, const char *); + +/* Imprime la définition d'un sous-identifiant pour un encodage. */ +bool write_encoding_spec_subid(const encoding_spec *, int, const char *); + +/* Imprime d'éventuels décrochages spécifiés pour un encodage. */ +bool write_encoding_spec_hooks(const encoding_spec *, int, const char *, bool); diff --git a/tools/d2c/grammar.y b/tools/d2c/grammar.y index 0c79f04..ad6531a 100644 --- a/tools/d2c/grammar.y +++ b/tools/d2c/grammar.y @@ -85,53 +85,55 @@ static void *map_input_data(const char *, size_t *); push_new_encoding_syntax(__spec); \ }) -#define handle_coder_asm(c, r) \ +#define handle_coder_subid(c, r) \ ({ \ encoding_spec *__spec; \ encoding_syntax *__syntax; \ - asm_pattern *__pattern; \ + instr_id *__subid; \ bool __status; \ __spec = get_current_encoding_spec(c); \ __syntax = get_current_encoding_syntax(__spec); \ - __pattern = get_asm_pattern_in_encoding_syntax(__syntax); \ - __status = load_asm_pattern_from_raw_line(__pattern, r); \ + __subid = get_encoding_syntax_subid(__syntax); \ + __status = load_id_from_raw_line(__subid, r); \ if (!__status) YYABORT; \ }) -#define handle_coder_conversions(c, r) \ +#define handle_coder_assertions(c, r) \ ({ \ encoding_spec *__spec; \ encoding_syntax *__syntax; \ - conv_list *__list; \ + disass_assert *__dassert; \ bool __status; \ __spec = get_current_encoding_spec(c); \ __syntax = get_current_encoding_syntax(__spec); \ - __list = get_conversions_in_encoding_syntax(__syntax); \ - __status = load_convs_from_raw_block(__list, r); \ + __dassert = get_assertions_for_encoding_syntax(__syntax); \ + __status = load_assertions_from_raw_block(__dassert, r); \ if (!__status) YYABORT; \ }) -#define handle_coder_assertions(c, r) \ +#define handle_coder_conversions(c, r) \ ({ \ encoding_spec *__spec; \ encoding_syntax *__syntax; \ - disass_assert *__dassert; \ + conv_list *__list; \ bool __status; \ __spec = get_current_encoding_spec(c); \ __syntax = get_current_encoding_syntax(__spec); \ - __dassert = get_assertions_for_encoding_syntax(__syntax); \ - __status = load_assertions_from_raw_block(__dassert, r); \ + __list = get_conversions_in_encoding_syntax(__syntax); \ + __status = load_convs_from_raw_block(__list, r); \ if (!__status) YYABORT; \ }) -#define handle_coder_hooks(c, r) \ +#define handle_coder_asm(c, r) \ ({ \ encoding_spec *__spec; \ - instr_hooks *__hooks;; \ + encoding_syntax *__syntax; \ + asm_pattern *__pattern; \ bool __status; \ __spec = get_current_encoding_spec(c); \ - __hooks = get_hooks_in_encoding_spec(__spec); \ - __status = load_hooks_from_raw_line(__hooks, r); \ + __syntax = get_current_encoding_syntax(__spec); \ + __pattern = get_asm_pattern_in_encoding_syntax(__syntax); \ + __status = load_asm_pattern_from_raw_line(__pattern, r); \ if (!__status) YYABORT; \ }) @@ -148,6 +150,17 @@ static void *map_input_data(const char *, size_t *); if (!__status) YYABORT; \ }) +#define handle_coder_hooks(c, r) \ + ({ \ + encoding_spec *__spec; \ + instr_hooks *__hooks;; \ + bool __status; \ + __spec = get_current_encoding_spec(c); \ + __hooks = get_hooks_in_encoding_spec(__spec); \ + __status = load_hooks_from_raw_line(__hooks, r); \ + if (!__status) YYABORT; \ + }) + } %union { @@ -184,7 +197,7 @@ YY_DECL; %token COPYRIGHT %token TITLE %token INS_NAME INS_SEP INS_DETAILS -%token ID +%token ID SUBID %token DESC %token ENCODING @@ -261,11 +274,14 @@ raw_content : /* empty */ | hooks raw_content raw_syntax : /* empty */ + | subid raw_syntax | assertions raw_syntax | conversions raw_syntax | asm raw_syntax | rules raw_syntax +subid : SUBID RAW_LINE { handle_coder_subid(coder, $2); } + assertions : ASSERT RAW_BLOCK { handle_coder_assertions(coder, $2); } conversions : CONV RAW_BLOCK { handle_coder_conversions(coder, $2); } diff --git a/tools/d2c/hooks/manager.c b/tools/d2c/hooks/manager.c index dc70c0c..35d6eba 100644 --- a/tools/d2c/hooks/manager.c +++ b/tools/d2c/hooks/manager.c @@ -24,6 +24,7 @@ #include "manager.h" +#include <assert.h> #include <malloc.h> #include <string.h> @@ -134,9 +135,32 @@ void register_hook_function(instr_hooks *hooks, char *type, char *name) /****************************************************************************** * * * Paramètres : hooks = gestionnaire d'un ensemble de fonctions associées. * +* * +* Description : Indique si des décrochages sont définis. * +* * +* Retour : Bilan de la consultation. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool has_hook_functions(const instr_hooks *hooks) +{ + bool result; /* Bilan à retourner */ + + result = (hooks->func_count > 0); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : hooks = gestionnaire d'un ensemble de fonctions associées. * * fd = descripteur d'un flux ouvert en écriture. * * * -* Description : Déclare des opérations complémentaires pour une instruction. * +* Description : Imprime une liste de décrochages spécifiés. * * * * Retour : Bilan de l'opération. * * * @@ -144,7 +168,7 @@ void register_hook_function(instr_hooks *hooks, char *type, char *name) * * ******************************************************************************/ -bool declare_hook_functions(const instr_hooks *hooks, int fd) +bool write_hook_functions(const instr_hooks *hooks, int fd) { bool result; /* Bilan à retourner */ size_t i; /* Boucle de parcours #1 */ @@ -173,55 +197,13 @@ bool declare_hook_functions(const instr_hooks *hooks, int fd) result = true; - if (hooks->func_count > 0) - { - dprintf(fd, "\tstatic const instr_hook_fc hooks[IPH_COUNT] = {\n\n"); - - for (i = 0; i < (sizeof(hook_types) / sizeof(hook_types[0])); i++) - { - func = find_hook_by_name(hooks, hook_types[i]); - - dprintf(fd, "\t\t[IPH_%s] = (instr_hook_fc)%s,\n", hook_types[i], func != NULL ? func->name : "NULL"); - - } - - dprintf(fd, "\n"); - - dprintf(fd, "\t};\n"); - - dprintf(fd, "\n"); - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : hooks = gestionnaire d'un ensemble de fonctions associées. * -* fd = descripteur d'un flux ouvert en écriture. * -* * -* Description : Associe dans le code des fonctions à une instruction. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool write_hook_functions(const instr_hooks *hooks, int fd) -{ - bool result; /* Bilan à retourner */ - - result = true; + assert(has_hook_functions(hooks)); - if (hooks->func_count > 0) + for (i = 0; i < (sizeof(hook_types) / sizeof(hook_types[0])); i++) { - dprintf(fd, "\tg_arch_instruction_set_hooks(result, hooks);\n"); + func = find_hook_by_name(hooks, hook_types[i]); - dprintf(fd, "\n"); + dprintf(fd, "\t\t[IPH_%s] = (instr_hook_fc)%s,\n", hook_types[i], func != NULL ? func->name : "NULL"); } diff --git a/tools/d2c/hooks/manager.h b/tools/d2c/hooks/manager.h index c07269e..49ebd19 100644 --- a/tools/d2c/hooks/manager.h +++ b/tools/d2c/hooks/manager.h @@ -43,10 +43,10 @@ void delete_instr_hooks(instr_hooks *); /* Enregistre l'utilité d'une fonction pour une instruction. */ void register_hook_function(instr_hooks *, char *, char *); -/* Déclare des opérations complémentaires pour une instruction. */ -bool declare_hook_functions(const instr_hooks *, int); +/* Indique si des décrochages sont définis. */ +bool has_hook_functions(const instr_hooks *); -/* Associe dans le code des fonctions à une instruction. */ +/* Imprime une liste de décrochages spécifiés. */ bool write_hook_functions(const instr_hooks *, int); diff --git a/tools/d2c/syntax.c b/tools/d2c/syntax.c index a38fdbb..dcac28e 100644 --- a/tools/d2c/syntax.c +++ b/tools/d2c/syntax.c @@ -32,6 +32,7 @@ /* Mémorisation d'une définition de syntaxe */ struct _encoding_syntax { + instr_id *subid; /* Gestionnaire d'identifiant */ disass_assert *assertions; /* Conditions de désassemblage */ conv_list *conversions; /* Conversions des données */ asm_pattern *pattern; /* Calligraphe d'assemblage */ @@ -59,6 +60,7 @@ encoding_syntax *create_encoding_syntax(void) result = (encoding_syntax *)calloc(1, sizeof(encoding_syntax)); + result->subid = create_instruction_id(); result->assertions = create_disass_assert(); result->conversions = create_conv_list(); result->pattern = create_asm_pattern(); @@ -83,6 +85,7 @@ encoding_syntax *create_encoding_syntax(void) void delete_encoding_syntax(encoding_syntax *syntax) { + delete_instruction_id(syntax->subid); delete_disass_assert(syntax->assertions); delete_conv_list(syntax->conversions); delete_asm_pattern(syntax->pattern); @@ -97,6 +100,25 @@ void delete_encoding_syntax(encoding_syntax *syntax) * * * Paramètres : syntax = définition de syntaxe à consulter. * * * +* Description : Fournit le gestionnaire des définitions d'identifiant. * +* * +* Retour : Structure assurant la définition d'identifiant. * +* * +* Remarques : - * +* * +******************************************************************************/ + +instr_id *get_encoding_syntax_subid(const encoding_syntax *syntax) +{ + return syntax->subid; + +} + + +/****************************************************************************** +* * +* Paramètres : syntax = définition de syntaxe à consulter. * +* * * Description : Fournit la liste de conditions préalables. * * * * Retour : Structure assurant la gestion de conditions de désassemblage.* @@ -235,6 +257,9 @@ bool declare_encoding_syntax(const encoding_syntax *syntax, int fd, const coding * bits = gestionnaire des bits d'encodage. * * alone = peut-on se placer en zone principale ? * * pp = pré-processeur pour les échanges de chaînes. * +* id = identifiant unique attribué à l'instruction. * +* sid = base d'identifiant unique attribué à l'encodage. * +* index = indice de la syntaxe dans l'encodage. * * exit = exprime le besoin d'une voie de sortie. [OUT] * * * * Description : Amorce la construction des éléments d'une syntaxe. * @@ -245,7 +270,7 @@ bool declare_encoding_syntax(const encoding_syntax *syntax, int fd, const coding * * ******************************************************************************/ -bool write_encoding_syntax(const encoding_syntax *syntax, int fd, const char *arch, const coding_bits *bits, bool alone, bool *exit) +bool write_encoding_syntax(const encoding_syntax *syntax, int fd, const char *arch, const coding_bits *bits, bool alone, const char *id, const char *sid, size_t index, bool *exit) { bool result; /* Bilan à retourner */ bool conditional; /* Définition sous condition ? */ @@ -290,8 +315,10 @@ bool write_encoding_syntax(const encoding_syntax *syntax, int fd, const char *ar dprintf(fd, "\n"); } - dprintf(fd, "\t%sresult = g_%s_instruction_new(\"%s\");\n", - tab, arch, get_keyword_from_asm_pattern(syntax->pattern)); + if (alone) + dprintf(fd, "\t%sresult = g_%s_instruction_new(%s, %s);\n", tab, arch, id, sid); + else + dprintf(fd, "\t%sresult = g_%s_instruction_new(%s, %s_%zu);\n", tab, arch, id, sid, index); dprintf(fd, "\n"); diff --git a/tools/d2c/syntax.h b/tools/d2c/syntax.h index 127d6ba..645f0ce 100644 --- a/tools/d2c/syntax.h +++ b/tools/d2c/syntax.h @@ -29,6 +29,7 @@ #include "assert/manager.h" #include "bits/manager.h" #include "conv/manager.h" +#include "id/manager.h" #include "pattern/manager.h" #include "rules/manager.h" @@ -44,6 +45,9 @@ encoding_syntax *create_encoding_syntax(void); /* Supprime de la mémoire le suivi d'une définition de syntaxe. */ void delete_encoding_syntax(encoding_syntax *); +/* Fournit le gestionnaire des définitions d'identifiant. */ +instr_id *get_encoding_syntax_subid(const encoding_syntax *); + /* Fournit la liste de conditions préalables. */ disass_assert *get_assertions_for_encoding_syntax(const encoding_syntax *); @@ -63,7 +67,7 @@ bool mark_syntax_items(const encoding_syntax *, const coding_bits *); bool declare_encoding_syntax(const encoding_syntax *, int, const coding_bits *); /* Amorce la construction des éléments d'une syntaxe. */ -bool write_encoding_syntax(const encoding_syntax *, int, const char *, const coding_bits *, bool, bool *); +bool write_encoding_syntax(const encoding_syntax *, int, const char *, const coding_bits *, bool, const char *, const char *, size_t, bool *); diff --git a/tools/d2c/tokens.l b/tools/d2c/tokens.l index 60dd257..6d32e33 100644 --- a/tools/d2c/tokens.l +++ b/tools/d2c/tokens.l @@ -85,6 +85,8 @@ <syntax_content>[ \t\n]+ { } +<syntax_content>"@subid" { yy_push_state(raw_line); return SUBID; } + <syntax_content>"@assert" { yy_push_state(raw_block); return ASSERT; } <syntax_content>"@conv" { yy_push_state(raw_block); return CONV; } |