summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/d2c/coder.c419
-rw-r--r--tools/d2c/coder.h12
-rw-r--r--tools/d2c/d2c.c18
-rw-r--r--tools/d2c/d2c.mk21
-rw-r--r--tools/d2c/encoding.c218
-rw-r--r--tools/d2c/encoding.h14
-rw-r--r--tools/d2c/grammar.y50
-rw-r--r--tools/d2c/hooks/manager.c78
-rw-r--r--tools/d2c/hooks/manager.h6
-rw-r--r--tools/d2c/syntax.c33
-rw-r--r--tools/d2c/syntax.h6
-rw-r--r--tools/d2c/tokens.l2
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; }