summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2016-05-22 15:43:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2016-05-22 15:43:43 (GMT)
commit7577eadd4e871d467f747c4927a1b1984d6a7606 (patch)
treee72a2fd5c1619e60402a678b0559079ed267eab0 /tools
parent33aa90b022e7d711a733ca7eb62c0b285f974317 (diff)
Extended the compiler to transform all the new ARMv7 encoding definitions.
Diffstat (limited to 'tools')
-rw-r--r--tools/d2c/args/grammar.y18
-rw-r--r--tools/d2c/args/manager.c201
-rw-r--r--tools/d2c/args/manager.h17
-rw-r--r--tools/d2c/args/tokens.l7
-rw-r--r--tools/d2c/bits/manager.c8
-rw-r--r--tools/d2c/conv/manager.c154
-rw-r--r--tools/d2c/conv/manager.h15
-rw-r--r--tools/d2c/d2c.mk3
-rwxr-xr-xtools/d2c/d2c_genmakefile.sh11
-rw-r--r--tools/d2c/grammar.y13
-rw-r--r--tools/d2c/pproc.c53
-rw-r--r--tools/d2c/pproc.h7
-rw-r--r--tools/d2c/rules/grammar.y3
-rw-r--r--tools/d2c/rules/manager.c330
-rw-r--r--tools/d2c/rules/manager.h8
-rw-r--r--tools/d2c/spec.c12
-rw-r--r--tools/d2c/syntax/manager.c63
-rw-r--r--tools/d2c/tokens.l4
18 files changed, 783 insertions, 144 deletions
diff --git a/tools/d2c/args/grammar.y b/tools/d2c/args/grammar.y
index 6477c47..f44a94b 100644
--- a/tools/d2c/args/grammar.y
+++ b/tools/d2c/args/grammar.y
@@ -50,18 +50,19 @@ YY_DECL;
%token FORCE_EXPR FORCE_CALL ALLOW_ALL
%token NAME
-%token NUMBER BINVAL HEXVAL
+%token NUMBER BINVAL HEXVAL STRING
%token COMMA COLON OP CP
-%token NOT AND_LOG EOR
+%token NOT AND_LOG EOR EQ NE
+%token AND_BOOL OR_BOOL
%type <string> NAME
%type <integer> NUMBER
-%type <string> BINVAL HEXVAL
+%type <string> BINVAL HEXVAL STRING
%type <operand> call
%type <args> arg_list
-%type <arg> arg_expr arg_composed
+%type <arg> arg_expr arg_logical_expr arg_composed
%type <un_op> arg_expr_un_op
%type <bin_op> arg_expr_bin_op
%type <string> arg_field
@@ -84,9 +85,13 @@ arg_expr : NAME { $$ = build_arg_expr_from_n
| NUMBER { $$ = build_arg_expr_from_number($1); }
| BINVAL { $$ = build_arg_expr_from_binval($1); }
| HEXVAL { $$ = build_arg_expr_from_hexval($1); }
+ | STRING { $$ = build_arg_expr_from_string($1); }
+ | arg_logical_expr { $$ = $1; }
| arg_composed { $$ = $1; }
| OP arg_expr CP { $$ = $2; }
| arg_expr_un_op arg_expr { $$ = build_unary_arg_expr($2, $1); }
+ | arg_expr EQ arg_expr { $$ = build_conditional_arg_expr($1, $3, true); }
+ | arg_expr NE arg_expr { $$ = build_conditional_arg_expr($1, $3, false); }
| arg_expr arg_expr_bin_op arg_expr { $$ = build_binary_arg_expr($1, $3, $2); }
arg_expr_un_op : NOT { $$ = CUO_NOT; }
@@ -94,6 +99,11 @@ arg_expr_un_op : NOT { $$ = CUO_NOT; }
arg_expr_bin_op : AND_LOG { $$ = CBO_AND; }
| EOR { $$ = CBO_EOR; }
+arg_logical_expr : arg_expr AND_BOOL arg_expr { $$ = build_logical_arg_expr($1, $3, true); }
+ | arg_logical_expr AND_BOOL arg_expr { $$ = build_logical_arg_expr($1, $3, true); }
+ | arg_expr OR_BOOL arg_expr { $$ = build_logical_arg_expr($1, $3, false); }
+ | arg_logical_expr OR_BOOL arg_expr { $$ = build_logical_arg_expr($1, $3, false); }
+
arg_composed : arg_field COLON arg_field { $$ = build_composed_arg_expr($1, $3); }
| arg_composed COLON arg_field { $$ = extend_composed_arg_expr($1, $3); }
diff --git a/tools/d2c/args/manager.c b/tools/d2c/args/manager.c
index ce300e6..498dd5c 100644
--- a/tools/d2c/args/manager.c
+++ b/tools/d2c/args/manager.c
@@ -41,8 +41,11 @@ typedef enum _ConvExprType
CET_NUMBER, /* Valeur codée en dur */
CET_BINVAL, /* Valeur binaire bxxx */
CET_HEXVAL, /* Valeur sous forme hexa. */
+ CET_STRING, /* Valeur sous forme de chaîne */
+ CET_LOGICAL, /* Expression booléenne logique*/
CET_COMPOSED, /* Agrégat de champs divers */
CET_UNARY, /* Opération unaire */
+ CET_CONDITIONAL, /* Valeur booléenne */
CET_BINARY, /* Opération binaire */
CET_COUNT
@@ -77,6 +80,18 @@ struct _arg_expr_t
/* CET_HEXVAL */
char *hexval; /* Valeur sous forme 0xxxx */
+ /* CET_STRING */
+ char *string; /* Chaîne "..." sans '"' */
+
+ /* CET_LOGICAL */
+ struct
+ {
+ arg_expr_t *logical_expr1; /* Expression à traiter */
+ arg_expr_t *logical_expr2; /* Expression à traiter */
+ bool and_op; /* Type de condition booléenne */
+
+ };
+
/* CET_COMPOSED */
struct
{
@@ -93,6 +108,15 @@ struct _arg_expr_t
};
+ /* CET_CONDITIONAL */
+ struct
+ {
+ arg_expr_t *cond_expr1; /* Expression à traiter */
+ arg_expr_t *cond_expr2; /* Expression à traiter */
+ bool cond_equal; /* Type de condition booléenne */
+
+ };
+
/* CET_BINARY */
struct
{
@@ -247,6 +271,64 @@ arg_expr_t *build_arg_expr_from_hexval(char *hexval)
/******************************************************************************
* *
+* Paramètres : number = valeur hexadécimale à conserver dans sa forme brute.*
+* *
+* Description : Conserve une valeur en tant qu'expression de conversion. *
+* *
+* Retour : Nouvelle expression mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+arg_expr_t *build_arg_expr_from_string(char *string)
+{
+ arg_expr_t *result; /* Structure à retourner */
+
+ result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+ result->type = CET_STRING;
+
+ result->string = string;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr1 = première expression à utiliser. *
+* expr2 = seconde expression à utiliser. *
+* and_op = choix de l'opérateur ('&&' ou '||'). *
+* *
+* Description : Construit une base d'expression booléenne logique. *
+* *
+* Retour : Nouvelle expression mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+arg_expr_t *build_logical_arg_expr(arg_expr_t *expr1, arg_expr_t *expr2, bool and_op)
+{
+ arg_expr_t *result; /* Structure à retourner */
+
+ result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+ result->type = CET_LOGICAL;
+
+ result->logical_expr1 = expr1;
+ result->logical_expr2 = expr2;
+ result->and_op = and_op;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : item1 = premier élément à agréger. *
* item2 = second élément à agréger. *
* *
@@ -346,6 +428,37 @@ arg_expr_t *build_unary_arg_expr(arg_expr_t *expr, ConvUnaryOperation op)
* *
******************************************************************************/
+arg_expr_t *build_conditional_arg_expr(arg_expr_t *expr1, arg_expr_t *expr2, bool eq)
+{
+ arg_expr_t *result; /* Structure à retourner */
+
+ result = (arg_expr_t *)calloc(1, sizeof(arg_expr_t));
+
+ result->type = CET_CONDITIONAL;
+
+ result->cond_expr1 = expr1;
+ result->cond_expr2 = expr2;
+ result->cond_equal = eq;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr1 = première expression à encapsuler. *
+* expr2 = seconde expression à encapsuler. *
+* op = opération binaire à associer à l'opération. *
+* *
+* Description : Traduit une opération binaire sur expression de conversion. *
+* *
+* Retour : Nouvelle expression mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
arg_expr_t *build_binary_arg_expr(arg_expr_t *expr1, arg_expr_t *expr2, ConvBinaryOperation op)
{
arg_expr_t *result; /* Structure à retourner */
@@ -394,6 +507,11 @@ void delete_arg_expr(arg_expr_t *expr)
free(expr->hexval);
break;
+ case CET_LOGICAL:
+ free(expr->logical_expr1);
+ free(expr->logical_expr2);
+ break;
+
case CET_COMPOSED:
for (i = 0; i < expr->comp_count; i++)
free(expr->comp_items[i]);
@@ -543,10 +661,20 @@ static bool visit_arg_expr(arg_expr_t *expr, visit_expr_fc visit, int fd, const
switch (expr->type)
{
+ case CET_LOGICAL:
+ result = visit_arg_expr(expr->logical_expr1, visit, fd, bits, list, data);
+ result = visit_arg_expr(expr->logical_expr2, visit, fd, bits, list, data);
+ break;
+
case CET_UNARY:
result = visit_arg_expr(expr->un_expr, visit, fd, bits, list, data);
break;
+ case CET_CONDITIONAL:
+ result = visit_arg_expr(expr->cond_expr1, visit, fd, bits, list, data);
+ result = visit_arg_expr(expr->cond_expr2, visit, fd, bits, list, data);
+ break;
+
case CET_BINARY:
result = visit_arg_expr(expr->bin_expr1, visit, fd, bits, list, data);
result = visit_arg_expr(expr->bin_expr2, visit, fd, bits, list, data);
@@ -643,7 +771,7 @@ bool ensure_arg_expr_content_fully_marked(arg_expr_t *expr, const coding_bits *b
if (field != NULL)
mark_raw_bitfield_as_used(field);
else /*if (func != NULL) */
- mark_conv_func(func, bts, lst);
+ mark_conv_func(func, true, bts, lst);
printf(" VAR '%s' found (bf=%d fc=%d)\n", name, !!field, !!func);
@@ -692,6 +820,7 @@ bool ensure_arg_expr_content_fully_marked(arg_expr_t *expr, const coding_bits *b
* arch = architecture visée par l'opération globale. *
* bits = gestionnaire des bits d'encodage. *
* list = liste de l'ensemble des fonctions de conversion. *
+* pp = pré-processeur pour les échanges de chaînes. *
* wide = taille des mots décodés. *
* *
* Description : S'assure de la déclaration des expressions pre-requises. *
@@ -702,9 +831,9 @@ bool ensure_arg_expr_content_fully_marked(arg_expr_t *expr, const coding_bits *b
* *
******************************************************************************/
-bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp, unsigned int wide)
{
- bool declare_sub_expr(arg_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, unsigned int *wide)
+ bool declare_sub_expr(arg_expr_t *sub, int f, const coding_bits *bts, const conv_list *lst, unsigned int *wideptr)
{
bool result; /* Bilan à retourner */
size_t i; /* Boucle de parcours */
@@ -713,7 +842,7 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
printf(" sub declared ? %d -- type = %d\n", sub->declared, sub->type);
if (sub->declared) return true;
- bool declare_by_name(int _f, const coding_bits *_bts, const conv_list *_lst, unsigned int _wide, const char *name)
+ bool declare_by_name(const char *name)
{
bool found; /* Bilan d'opération à renvoyer*/
conv_func *func; /* Eventuelle fonction liée */
@@ -723,7 +852,7 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
if (found && func != NULL)
{
printf("========= DECLARE for '%s'\n", name);
- found = declare_conv_func(func, _f, _bts, _lst, _wide);
+ found = declare_conv_func(func, fd, bits, list, pp, wide);
printf("========= END DECLARE for '%s'\n", name);
/**
@@ -733,10 +862,13 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
* car les appels racine servent directement d'arguments.
*/
+ /*
if (is_conv_func_expression(func))
- dprintf(_f, "\t\tuint%u_t val_%s; // Ho\n", _wide, name);
+ dprintf(_f, "\t\tuint%u_t val_%s; // Ho\n", _wide, name); // FIXME
else
- dprintf(_f, "\t\tGArchOperand *val_%s;;;;;\n", name);
+ dprintf(_f, "\t\tGArchOperand *val_%s;;;;;\n", name); // FIXME
+ */
+
}
@@ -748,7 +880,7 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
switch (sub->type)
{
case CET_NAME:
- /* result = */declare_by_name(f, bits, lst, *wide, sub->name);
+ /* result = */declare_by_name(sub->name);
result = true;
break;
@@ -756,10 +888,7 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
result = true;
for (i = 0; i < sub->comp_count && result; i++)
if (!isdigit(sub->comp_items[i][0]))
- printf("... trying to declare... '%s'\n", sub->comp_items[i]);
- for (i = 0; i < sub->comp_count && result; i++)
- if (!isdigit(sub->comp_items[i][0]))
- result = declare_by_name(f, bits, lst, *wide, sub->comp_items[i]);
+ result = declare_by_name(sub->comp_items[i]);
break;
default:
@@ -787,6 +916,7 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
* bits = gestionnaire des bits d'encodage. *
* list = liste de l'ensemble des fonctions de conversion. *
* pp = pré-processeur pour les échanges de chaînes. *
+* exit = exprime le besoin d'une voie de sortie. [OUT] *
* *
* Description : S'assure de la définition des expressions pre-requises. *
* *
@@ -796,7 +926,7 @@ bool ensure_arg_expr_content_fully_declared(arg_expr_t *expr, int fd, const codi
* *
******************************************************************************/
-bool ensure_arg_expr_content_fully_defined(arg_expr_t *expr, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+bool ensure_arg_expr_content_fully_defined(arg_expr_t *expr, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
{
typedef struct _def_info
{
@@ -823,7 +953,7 @@ bool ensure_arg_expr_content_fully_defined(arg_expr_t *expr, int fd, const char
found = find_var_by_name(bts, lst, name, NULL, &func);
if (found && func != NULL)
- found = define_conv_func(func, false, false, _f, _info->arch, _bts, _lst, _info->pp);
+ found = define_conv_func(func, false, false, _f, _info->arch, _bts, _lst, _info->pp, exit);
return found;
@@ -920,12 +1050,24 @@ bool define_arg_expr(const arg_expr_t *expr, int fd, const coding_bits *bits, co
dprintf(fd, "0x%s", expr->hexval);
break;
+ case CET_STRING:
+ dprintf(fd, "\"%s\"", expr->string);
+ break;
+
+ case CET_LOGICAL:
+
+ result = define_arg_expr(expr->logical_expr1, fd, bits, list);
+
+ dprintf(fd, expr->and_op ? " && " : " || ");
+
+ result &= define_arg_expr(expr->logical_expr2, fd, bits, list);
+
+ break;
+
case CET_COMPOSED:
result = compute_arg_expr_size(expr, bits, list, &max_size);
- printf("MAX SIZE :: %u\n", max_size);
-
for (i = 0; i < expr->comp_count && result; i++)
{
cname = expr->comp_items[i];
@@ -998,6 +1140,23 @@ bool define_arg_expr(const arg_expr_t *expr, int fd, const coding_bits *bits, co
break;
+ case CET_CONDITIONAL:
+
+ dprintf(fd, "(");
+
+ result = define_arg_expr(expr->cond_expr1, fd, bits, list);
+
+ if (expr->cond_equal)
+ dprintf(fd, " == ");
+ else
+ dprintf(fd, " != ");
+
+ result &= define_arg_expr(expr->cond_expr2, fd, bits, list);
+
+ dprintf(fd, ")");
+
+ break;
+
case CET_BINARY:
dprintf(fd, "(");
@@ -1154,6 +1313,7 @@ bool ensure_arg_list_content_fully_marked(arg_list_t *args, const coding_bits *b
* fd = descripteur d'un flux ouvert en écriture. *
* bits = gestionnaire des bits d'encodage. *
* list = liste de l'ensemble des fonctions de conversion. *
+* pp = pré-processeur pour les échanges de chaînes. *
* wide = taille des mots décodés. *
* *
* Description : S'assure de la déclaration des expressions pre-requises. *
@@ -1164,7 +1324,7 @@ bool ensure_arg_list_content_fully_marked(arg_list_t *args, const coding_bits *b
* *
******************************************************************************/
-bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp, unsigned int wide)
{
bool result; /* Bilan à remonter */
size_t i; /* Boucle de parcours */
@@ -1172,7 +1332,7 @@ bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const codi
result = true;
for (i = 0; i < args->count && result; i++)
- result = ensure_arg_expr_content_fully_declared(args->items[i], fd, bits, list, wide);
+ result = ensure_arg_expr_content_fully_declared(args->items[i], fd, bits, list, pp, wide);
return result;
@@ -1187,6 +1347,7 @@ bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const codi
* bits = gestionnaire des bits d'encodage. *
* list = liste de l'ensemble des fonctions de conversion. *
* pp = pré-processeur pour les échanges de chaînes. *
+* exit = exprime le besoin d'une voie de sortie. [OUT] *
* *
* Description : S'assure de la définition des expressions pre-requises. *
* *
@@ -1196,7 +1357,7 @@ bool ensure_arg_list_content_fully_declared(arg_list_t *args, int fd, const codi
* *
******************************************************************************/
-bool ensure_arg_list_content_fully_defined(arg_list_t *args, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+bool ensure_arg_list_content_fully_defined(arg_list_t *args, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
{
bool result; /* Bilan à remonter */
size_t i; /* Boucle de parcours */
@@ -1204,7 +1365,7 @@ bool ensure_arg_list_content_fully_defined(arg_list_t *args, int fd, const char
result = true;
for (i = 0; i < args->count && result; i++)
- result = ensure_arg_expr_content_fully_defined(args->items[i], fd, arch, bits, list, pp);
+ result = ensure_arg_expr_content_fully_defined(args->items[i], fd, arch, bits, list, pp, exit);
return result;
diff --git a/tools/d2c/args/manager.h b/tools/d2c/args/manager.h
index 85fc0a8..111b6db 100644
--- a/tools/d2c/args/manager.h
+++ b/tools/d2c/args/manager.h
@@ -73,6 +73,12 @@ arg_expr_t *build_arg_expr_from_binval(char *);
/* Conserve une valeur en tant qu'expression de conversion. */
arg_expr_t *build_arg_expr_from_hexval(char *);
+/* Conserve une valeur en tant qu'expression de conversion. */
+arg_expr_t *build_arg_expr_from_string(char *);
+
+/* Construit une base d'expression booléenne logique. */
+arg_expr_t *build_logical_arg_expr(arg_expr_t *, arg_expr_t *, bool);
+
/* Construit une base d'expression de conversion composée. */
arg_expr_t *build_composed_arg_expr(char *, char *);
@@ -83,6 +89,9 @@ arg_expr_t *extend_composed_arg_expr(arg_expr_t *, char *);
arg_expr_t *build_unary_arg_expr(arg_expr_t *, ConvUnaryOperation);
/* Traduit une opération binaire sur expression de conversion. */
+arg_expr_t *build_conditional_arg_expr(arg_expr_t *, arg_expr_t *, bool);
+
+/* Traduit une opération binaire sur expression de conversion. */
arg_expr_t *build_binary_arg_expr(arg_expr_t *, arg_expr_t *, ConvBinaryOperation);
/* Supprime tous les éléments mis en place pour un argument. */
@@ -95,10 +104,10 @@ bool compute_arg_expr_size(const arg_expr_t *, const coding_bits *, const conv_l
bool ensure_arg_expr_content_fully_marked(arg_expr_t *, const coding_bits *, const conv_list *);
/* S'assure de la déclaration des expressions pre-requises. */
-bool ensure_arg_expr_content_fully_declared(arg_expr_t *, int, const coding_bits *, const conv_list *, unsigned int);
+bool ensure_arg_expr_content_fully_declared(arg_expr_t *, int, const coding_bits *, const conv_list *, const pre_processor *, unsigned int);
/* S'assure de la définition des expressions pre-requises. */
-bool ensure_arg_expr_content_fully_defined(arg_expr_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
+bool ensure_arg_expr_content_fully_defined(arg_expr_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
/* Définit une expression utilisée dans une conversion. */
bool define_arg_expr(const arg_expr_t *, int, const coding_bits *, const conv_list *);
@@ -125,10 +134,10 @@ arg_list_t *extend_arg_list(arg_list_t *, arg_expr_t *);
bool ensure_arg_list_content_fully_marked(arg_list_t *, const coding_bits *, const conv_list *);
/* S'assure de la déclaration des expressions pre-requises. */
-bool ensure_arg_list_content_fully_declared(arg_list_t *, int, const coding_bits *, const conv_list *, unsigned int);
+bool ensure_arg_list_content_fully_declared(arg_list_t *, int, const coding_bits *, const conv_list *, const pre_processor *, unsigned int);
/* S'assure de la définition des expressions pre-requises. */
-bool ensure_arg_list_content_fully_defined(arg_list_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
+bool ensure_arg_list_content_fully_defined(arg_list_t *, int, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
/* Définit les variables associées à un appel de fonction. */
bool define_arg_list(const arg_list_t *, int, const coding_bits *, const conv_list *);
diff --git a/tools/d2c/args/tokens.l b/tools/d2c/args/tokens.l
index 4b1a2a1..2a4ffb2 100644
--- a/tools/d2c/args/tokens.l
+++ b/tools/d2c/args/tokens.l
@@ -51,12 +51,19 @@
<binval>[01][01]* { yylvalp->string = strdup(yytext); return BINVAL; }
<binval>"'" { yy_pop_state(); }
+\"[^\"]*\" { yylvalp->string = strndup(yytext + 1, strlen(yytext) - 2); printf("str = '%s'\n", yylvalp->string); return STRING; }
+
"0x" { yy_push_state(hexval); }
<hexval>[0-9a-f][0-9a-f]* { yylvalp->string = strdup(yytext); yy_pop_state(); return HEXVAL; }
"," { return COMMA; }
":" { return COLON; }
"&" { return AND_LOG; }
+"==" { return EQ; }
+"!=" { return NE; }
+
+"&&" { return AND_BOOL; }
+"||" { return OR_BOOL; }
"(" { yy_push_state(INITIAL); return OP; }
")" { yy_pop_state(); return CP; }
diff --git a/tools/d2c/bits/manager.c b/tools/d2c/bits/manager.c
index cc2783b..edf682d 100644
--- a/tools/d2c/bits/manager.c
+++ b/tools/d2c/bits/manager.c
@@ -366,9 +366,12 @@ bool check_bits_correctness(const coding_bits *bits, int fd)
bool define_used_bits_fields(const coding_bits *bits, int fd)
{
+ bool got_one; /* Suit le nombre d'impressions*/
size_t i; /* Boucle de parcours */
raw_bitfield *rf; /* Accès confortable à un champ*/
+ got_one = false;
+
for (i = 0; i < bits->bf_count; i++)
{
rf = &bits->fields[i];
@@ -376,8 +379,13 @@ bool define_used_bits_fields(const coding_bits *bits, int fd)
dprintf(fd, "\t\traw_%s = (_raw >> %u) & 0x%llx;\n", rf->name, rf->start, (1ull << rf->length) - 1);
+ got_one = true;
+
}
+ if (got_one)
+ dprintf(fd, "\n");
+
return true;
}
diff --git a/tools/d2c/conv/manager.c b/tools/d2c/conv/manager.c
index fca9ce0..09368ce 100644
--- a/tools/d2c/conv/manager.c
+++ b/tools/d2c/conv/manager.c
@@ -42,6 +42,8 @@
/* Fonction de conversion */
struct _conv_func
{
+ bool used; /* Conversion utilisée ? */
+ bool intermediate; /* Variable intermédiaire ? */
bool declared; /* Expression déjà déclarée ? */
bool defined; /* Expression déjà définie ? */
@@ -241,9 +243,10 @@ bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, cons
/******************************************************************************
* *
-* Paramètres : func = fonction de conversion à manipuler. *
-* bits = gestionnaire des bits d'encodage. *
-* list = liste de l'ensemble des fonctions de conversion. *
+* Paramètres : func = fonction de conversion à manipuler. *
+* inter = note un résultat de conversion comme intermédiaire. *
+* bits = gestionnaire des bits d'encodage. *
+* list = liste de l'ensemble des fonctions de conversion. *
* *
* Description : Marque les champs utilisés par une fonction de conversion. *
* *
@@ -253,10 +256,13 @@ bool compute_conv_func_size(const conv_func *func, const coding_bits *bits, cons
* *
******************************************************************************/
-bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *list)
+bool mark_conv_func(conv_func *func, bool inter, const coding_bits *bits, const conv_list *list)
{
bool result; /* Bilan à remonter */
+ func->used = true;
+ func->intermediate |= inter;
+
if (func->is_expr)
result = ensure_arg_expr_content_fully_marked(func->expr, bits, list);
else
@@ -273,6 +279,7 @@ bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *l
* fd = descripteur d'un flux ouvert en écriture. *
* bits = gestionnaire des bits d'encodage. *
* list = liste de l'ensemble des fonctions de conversion. *
+* pp = pré-processeur pour les échanges de chaînes. *
* wide = taille des mots décodés. *
* *
* Description : Déclare les variables associées à une fonction de conversion.*
@@ -283,18 +290,31 @@ bool mark_conv_func(conv_func *func, const coding_bits *bits, const conv_list *l
* *
******************************************************************************/
-bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, unsigned int wide)
+bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp, unsigned int wide)
{
bool result; /* Bilan à remonter */
+ printf(" -> declaration for '%s': declared ? %d - expr ? %d\n",
+ func->dest, func->declared, func->is_expr);
+
+ assert(func->used);
+
/* Si la fonction a déjà été définie lors d'un précédent besoin... */
if (func->declared) return true;
if (func->is_expr)
- result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, wide);
+ result = ensure_arg_expr_content_fully_declared(func->expr, fd, bits, list, pp, wide);
else
- result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, wide);
+ result = ensure_arg_list_content_fully_declared(func->args, fd, bits, list, pp, wide);
+
+ if (result && func->intermediate)
+ {
+ if (!func->is_expr && is_operand_producer(pp, func->name))
+ dprintf(fd, "\t\tGArchOperand *val_%s;\n", func->dest);
+ else
+ dprintf(fd, "\t\tuint%u_t val_%s;\n", wide, func->dest);
+ }
func->declared = result;
@@ -305,6 +325,25 @@ bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const c
/******************************************************************************
* *
+* Paramètres : func = fonction de conversion à consulter. *
+* *
+* Description : Indique si une conversion a déjà été définie. *
+* *
+* Retour : Etat de la définition. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool is_conv_func_already_defined(const conv_func *func)
+{
+ return func->defined;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : func = fonction de conversion à manipuler. *
* last = précise si la conversion est la dernière. *
* internal = indique le type de manipulation finale. *
@@ -313,6 +352,7 @@ bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const c
* bits = gestionnaire des bits d'encodage. *
* list = liste de l'ensemble des fonctions de conversion. *
* pp = pré-processeur pour les échanges de chaînes. *
+* exit = exprime le besoin d'une voie de sortie. [OUT] *
* *
* Description : Définit les variables associées à une fonction de conversion.*
* *
@@ -322,7 +362,7 @@ bool declare_conv_func(conv_func *func, int fd, const coding_bits *bits, const c
* *
******************************************************************************/
-bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const char *arch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
{
bool result; /* Bilan à remonter */
const char *callable; /* Fonction à appeler */
@@ -331,9 +371,9 @@ bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const c
if (func->defined) return true;
if (func->is_expr)
- result = ensure_arg_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp);
+ result = ensure_arg_expr_content_fully_defined(func->expr, fd, arch, bits, list, pp, exit);
else
- result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp);
+ result = ensure_arg_list_content_fully_defined(func->args, fd, arch, bits, list, pp, exit);
/* Nom de la fonction effectivement appelée */
@@ -396,6 +436,12 @@ bool define_conv_func(conv_func *func, bool last, bool internal, int fd, const c
dprintf(fd, ";\n");
+ if (!func->is_expr && is_operand_producer(pp, func->name))
+ {
+ dprintf(fd, "\t\tif (val_%s == NULL) goto bad_exit;\n", func->dest);
+ *exit = true;
+ }
+
}
func->defined = result;
@@ -516,3 +562,91 @@ conv_func *find_named_conv_in_list(const conv_list *list, const char *name)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = liste de fonctions de conversion à consulter. *
+* fd = descripteur d'un flux ouvert en écriture. *
+* bits = gestionnaire des bits d'encodage. *
+* pp = pré-processeur pour les échanges de chaînes. *
+* wide = taille des mots décodés. *
+* *
+* Description : Déclare l'ensemble des variables intermédiaires. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool declare_used_intermediate_conversions(const conv_list *list, int fd, const coding_bits *bits, const pre_processor *pp, unsigned int wide)
+{
+ bool result; /* Bilan à remonter */
+ size_t i; /* Boucle de parcours */
+ conv_func *func; /* Conversion à traiter */
+
+ result = true;
+
+ for (i = 0; i < list->func_count && result; i++)
+ {
+ func = list->functions[i];
+
+ if (func->used && func->intermediate)
+ result = declare_conv_func(func, fd, bits, list, pp, wide);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : list = liste de fonctions de conversion à consulter. *
+* fd = descripteur d'un flux ouvert en écriture. *
+* arch = architecture visée par l'opération globale. *
+* bits = gestionnaire des bits d'encodage. *
+* pp = pré-processeur pour les échanges de chaînes. *
+* exit = exprime le besoin d'une voie de sortie. [OUT] *
+* *
+* Description : Définit l'ensemble des variables intermédiaires. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool define_used_intermediate_conversions(const conv_list *list, int fd, const char *arch, const coding_bits *bits, const pre_processor *pp, bool *exit)
+{
+ bool result; /* Bilan à remonter */
+ bool got_one; /* Suit le nombre d'impressions*/
+ size_t i; /* Boucle de parcours */
+ conv_func *func; /* Conversion à traiter */
+
+ result = true;
+
+ got_one = false;
+
+ for (i = 0; i < list->func_count && result; i++)
+ {
+ func = list->functions[i];
+
+ if (func->used && func->intermediate)
+ {
+ result = define_conv_func(func, false, false, fd, arch, bits, list, pp, exit);
+
+ got_one = true;
+
+ }
+
+ }
+
+ if (got_one)
+ dprintf(fd, "\n");
+
+ return result;
+
+}
diff --git a/tools/d2c/conv/manager.h b/tools/d2c/conv/manager.h
index abd6c6f..3ea64fb 100644
--- a/tools/d2c/conv/manager.h
+++ b/tools/d2c/conv/manager.h
@@ -60,13 +60,16 @@ bool is_conv_func_expression(const conv_func *);
bool compute_conv_func_size(const conv_func *, const coding_bits *, const conv_list *, unsigned int *);
/* Marque les champs utilisés par une fonction de conversion. */
-bool mark_conv_func(conv_func *, const coding_bits *, const conv_list *);
+bool mark_conv_func(conv_func *, bool, const coding_bits *, const conv_list *);
/* Déclare les variables associées à une fonction de conversion. */
-bool declare_conv_func(conv_func *, int, const coding_bits *, const conv_list *, unsigned int);
+bool declare_conv_func(conv_func *, int, const coding_bits *, const conv_list *, const pre_processor *, unsigned int);
+
+/* Indique si une conversion a déjà été définie. */
+bool is_conv_func_already_defined(const conv_func *);
/* Définit les variables associées à une fonction de conversion. */
-bool define_conv_func(conv_func *, bool, bool, int, const char *, const coding_bits *, const conv_list *, const pre_processor *);
+bool define_conv_func(conv_func *, bool, bool, int, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
@@ -89,6 +92,12 @@ void register_conversion(conv_list *, conv_func *);
/* Recherche un résultat précis dans une liste de fonctions. */
conv_func *find_named_conv_in_list(const conv_list *, const char *);
+/* Déclare l'ensemble des variables intermédiaires. */
+bool declare_used_intermediate_conversions(const conv_list *, int, const coding_bits *, const pre_processor *, unsigned int);
+
+/* Définit l'ensemble des variables intermédiaires. */
+bool define_used_intermediate_conversions(const conv_list *, int, const char *, const coding_bits *, const pre_processor *, bool *);
+
#endif /* _TOOLS_D2C_CONV_MANAGER_H */
diff --git a/tools/d2c/d2c.mk b/tools/d2c/d2c.mk
index 0731329..d0a4698 100644
--- a/tools/d2c/d2c.mk
+++ b/tools/d2c/d2c.mk
@@ -17,6 +17,7 @@ fix_verbose_0 = echo " FIX " `basename $$f`;
# D2C_HEADER =
# D2C_ENCODINGS =
# D2C_MACROS =
+# D2C_OPERANDS =
# D2C_PREFIX =
# FIXED_C_INCLUDES =
@@ -26,7 +27,7 @@ fix_verbose_0 = echo " FIX " `basename $$f`;
SUFFIXES = .g
.d.g:
- $(d2c_verbose)$(D2C_BIN) -i $< -t $(D2C_TYPE) -d $(D2C_OUTDIR) -a $(D2C_ARCH) -H $(D2C_HEADER) $(D2C_ENCODINGS) $(D2C_MACROS) -p $(D2C_PREFIX)
+ $(d2c_verbose)$(D2C_BIN) -i $< -t $(D2C_TYPE) -d $(D2C_OUTDIR) -a $(D2C_ARCH) -H $(D2C_HEADER) $(D2C_ENCODINGS) $(D2C_MACROS) $(D2C_OPERANDS) -p "$(D2C_PREFIX)"
@touch $@
d2c_final_rules: fix_includes_in_c_templates fix_includes_in_h_templates untabify_disass
diff --git a/tools/d2c/d2c_genmakefile.sh b/tools/d2c/d2c_genmakefile.sh
index 7911d04..be303e0 100755
--- a/tools/d2c/d2c_genmakefile.sh
+++ b/tools/d2c/d2c_genmakefile.sh
@@ -47,7 +47,7 @@ do
arch_name_dotted="${arch}_."
fi
- $echo -n "${arch_name}HEADER_FILES =" | tr [a-z] [A-Z] >> ${MAKEFILE_TMP}
+ $echo -n "${arch_name}HEADER_FILES =" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
has_header=""
@@ -75,7 +75,7 @@ do
$echo >> ${MAKEFILE_TMP}
$echo -n "${arch_name}opcodes.h: " >> ${MAKEFILE_TMP}
- $echo "\$(${arch_name}HEADER_FILES)" | tr [a-z] [A-Z] >> ${MAKEFILE_TMP}
+ $echo "\$(${arch_name}HEADER_FILES)" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
if [ -z "${has_header}" ]; then
@@ -98,7 +98,6 @@ done
$echo >> ${MAKEFILE_TMP}
-
# Génération des codes d'instructions
for op in $OPCODES;
@@ -121,7 +120,7 @@ do
continue
fi
- $echo -n "${op}_${arch_name}FILES =" | tr [a-z] [A-Z] >> ${MAKEFILE_TMP}
+ $echo -n "${op}_${arch_name}FILES =" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
for src in ${sources};
do
@@ -133,12 +132,12 @@ do
$echo >> ${MAKEFILE_TMP}
$echo -n "${arch_name}${op}.c: " >> ${MAKEFILE_TMP}
- $echo -n "\$(${op}_${arch_name}FILES)" | tr [a-z] [A-Z] >> ${MAKEFILE_TMP}
+ $echo -n "\$(${op}_${arch_name}FILES)" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
$echo " ${arch_name}opcodes.h" >> ${MAKEFILE_TMP}
$echo -e "\t\$(cini_verbose)cat ${input}/${arch_name_dotted}${op}.tmpl.c > \$@" >> ${MAKEFILE_TMP}
$echo -ne "\t\$(cgen_verbose)cat \$(" >> ${MAKEFILE_TMP}
- $echo -ne "${op}_${arch_name}FILES" | tr [a-z] [A-Z] >> ${MAKEFILE_TMP}
+ $echo -ne "${op}_${arch_name}FILES" | tr [:lower:] [:upper:] >> ${MAKEFILE_TMP}
$echo -e ") >> \$@" >> ${MAKEFILE_TMP}
$echo >> ${MAKEFILE_TMP}
diff --git a/tools/d2c/grammar.y b/tools/d2c/grammar.y
index ec7da60..063d22b 100644
--- a/tools/d2c/grammar.y
+++ b/tools/d2c/grammar.y
@@ -138,6 +138,7 @@ YY_DECL;
%token COPYRIGHT
%token TITLE
%token INS_NAME INS_SEP INS_DETAILS
+%token DESC
%token ENCODING
%token TYPE NUMBER
@@ -167,10 +168,12 @@ YY_DECL;
input : name encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; }
+ | name desc encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; }
name : COPYRIGHT TITLE INS_NAME { save_notes_for_coder(coder, $1, $3, '\0', NULL); }
| COPYRIGHT TITLE INS_NAME INS_SEP INS_DETAILS { save_notes_for_coder(coder, $1, $3, $4, $5); }
+desc : DESC RAW_LINE
encodings : /* empty */
| encoding encodings
@@ -273,7 +276,8 @@ static void show_usage(const char *argv0)
printf("\t-a | --arch <string>\t\tDefine the archicture to handle.\n");
printf("\t-H | --header <string>\t\tSet the base of the #ifndef / #define game.\n");
printf("\t-e | --encoding <none|string>\tDefine encoding prefixes for files.\n");
- printf("\t-m | --macro <string>\t\tRegister some conversion functions.\n");
+ printf("\t-M | --macro <string>\t\tRegister some conversion functions.\n");
+ printf("\t-n | --operand <string>\t\tRegister a function producing final operands.\n");
printf("\t-p | --prefix <string>\t\tDefine a prefix to format operand type constants (see -t).\n");
printf("\n");
@@ -375,6 +379,7 @@ int main(int argc, char **argv)
{ "header", required_argument, NULL, 'H' },
{ "encoding", required_argument, NULL, 'e' },
{ "macro", required_argument, NULL, 'M' },
+ { "operand", required_argument, NULL, 'n' },
{ "prefix", required_argument, NULL, 'p' },
{ NULL, 0, NULL, 0 }
@@ -391,7 +396,7 @@ int main(int argc, char **argv)
while (!has_error)
{
- ret = getopt_long(argc, argv, "hi:t:d:a:H:e:M:p:", long_options, &index);
+ ret = getopt_long(argc, argv, "hi:t:d:a:H:e:M:n:p:", long_options, &index);
if (ret == -1) break;
switch (ret)
@@ -456,6 +461,10 @@ int main(int argc, char **argv)
break;
+ case 'n':
+ register_as_operand_producer(get_coder_pre_proc(coder), optarg);
+ break;
+
case 'p':
set_coder_const_prefix(coder, optarg);
break;
diff --git a/tools/d2c/pproc.c b/tools/d2c/pproc.c
index fb72774..ec397f3 100644
--- a/tools/d2c/pproc.c
+++ b/tools/d2c/pproc.c
@@ -38,6 +38,9 @@ struct _pre_processor
string_exch *macros; /* Remplacements de chaînes */
size_t macros_count; /* Nombre de ces remplacements */
+ const char **op_producers; /* Producteurs d'opérandes */
+ size_t op_prod_count; /* Quantité de producteurs */
+
};
@@ -238,3 +241,53 @@ const char *find_macro(const pre_processor *pp, const char *src)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : pp = pré-processeur dont le contenu est à compléter. *
+* func = fonction produisant un opérande final. *
+* *
+* Description : Mémorise une fonction comme produisant un opérateur final. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void register_as_operand_producer(pre_processor *pp, const char *func)
+{
+ pp->op_producers = (const char **)realloc(pp->op_producers, ++pp->op_prod_count * sizeof(const char **));
+
+ pp->op_producers[pp->op_prod_count - 1] = func;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : pp = pré-processeur dont le contenu est à consulter. *
+* func = fonction dont la nature du résultat est recherchée. *
+* *
+* Description : Détermine si une fonction produit un opérande ou non. *
+* *
+* Retour : true si la fonction fournie produit un opérande final. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool is_operand_producer(const pre_processor *pp, const char *func)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = false;
+
+ for (i = 0; i < pp->op_prod_count && !result; i++)
+ result = (strcmp(pp->op_producers[i], func) == 0);
+
+ return result;
+
+}
diff --git a/tools/d2c/pproc.h b/tools/d2c/pproc.h
index a2812f8..4ccdf32 100644
--- a/tools/d2c/pproc.h
+++ b/tools/d2c/pproc.h
@@ -25,6 +25,7 @@
#define _TOOLS_D2C_PPROC_H
+#include <stdbool.h>
#include <sys/types.h>
@@ -65,6 +66,12 @@ void define_macro(pre_processor *, const char *, const char *);
/* Recherche l'existence d'une macro pour un remplacement. */
const char *find_macro(const pre_processor *, const char *);
+/* Mémorise une fonction comme produisant un opérateur final. */
+void register_as_operand_producer(pre_processor *, const char *);
+
+/* Détermine si une fonction produit un opérande ou non. */
+bool is_operand_producer(const pre_processor *, const char *);
+
#endif /* _TOOLS_D2C_PPROC_H */
diff --git a/tools/d2c/rules/grammar.y b/tools/d2c/rules/grammar.y
index effd4b3..bf5b3c2 100644
--- a/tools/d2c/rules/grammar.y
+++ b/tools/d2c/rules/grammar.y
@@ -74,7 +74,8 @@ rules_list : /* empty */
rule : IF EXPR_START rule_cond EXPR_END THEN action { register_conditional_rule(rules, $3, &$6); }
| action { register_conditional_rule(rules, NULL, &$1); }
-rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); }
+rule_cond : NAME { $$ = build_named_cond_expression($1); }
+ | NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); }
| NAME EQUAL HEXVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, false); }
| NAME AND_LOG BINVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, true); }
| NAME AND_LOG HEXVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, false); }
diff --git a/tools/d2c/rules/manager.c b/tools/d2c/rules/manager.c
index 6c1f069..88ee4b9 100644
--- a/tools/d2c/rules/manager.c
+++ b/tools/d2c/rules/manager.c
@@ -24,6 +24,7 @@
#include "manager.h"
+#include <assert.h>
#include <malloc.h>
#include <stdbool.h>
#include <string.h>
@@ -37,13 +38,24 @@
/* -------------------------- CONDITIONS DE DECLENCHEMENTS -------------------------- */
+/* Type d'informations contenues */
+typedef enum _CondExprType
+{
+ CET_NAMED, /* Référence à une variable */
+ CET_SIMPLE, /* Version simple */
+ CET_COMPOSED /* Version composée */
+
+} CondExprType;
+
/* Expression d'une condition */
struct _cond_expr
{
- bool is_simple; /* Sélection de champ */
+ CondExprType type; /* Sélection de champ */
union
{
+ char *named; /* Référence à une variable */
+
struct
{
char *variable; /* Variable manipulée */
@@ -70,8 +82,11 @@ struct _cond_expr
/* Libère de la mémoire une expression conditionnelle. */
static void delete_cond_expr(cond_expr *);
+/* Marque les éléments de conditions comme utilisés. */
+static bool mark_cond_expr(const cond_expr *, const coding_bits *, const conv_list *);
+
/* Traduit en code une expression de condition. */
-static bool write_cond_expr(const cond_expr *, int, const coding_bits *);
+static bool write_cond_expr(const cond_expr *, int, const coding_bits *, const conv_list *);
@@ -104,6 +119,33 @@ struct _decoding_rules
/******************************************************************************
* *
* Paramètres : variable = désignation de la variable à manipuler. *
+* *
+* Description : Crée une expression conditionnelle reposant sur une variable.*
+* *
+* Retour : Structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+cond_expr *build_named_cond_expression(char *variable)
+{
+ cond_expr *result; /* Structure à retourner */
+
+ result = (cond_expr *)calloc(1, sizeof(cond_expr));
+
+ result->type = CET_NAMED;
+
+ result->named = make_string_lower(variable);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : variable = désignation de la variable à manipuler. *
* comp = type de comparaison à utiliser. *
* value = valeur binaire à comparer. *
* is_binary = indique la nature de la valeur transmise. *
@@ -122,7 +164,7 @@ cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char
result = (cond_expr *)calloc(1, sizeof(cond_expr));
- result->is_simple = true;
+ result->type = CET_SIMPLE;
result->simple.variable = make_string_lower(variable);
result->simple.comp = comp;
@@ -155,7 +197,7 @@ cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, con
result = (cond_expr *)calloc(1, sizeof(cond_expr));
- result->is_simple = false;
+ result->type = CET_COMPOSED;
result->composed.a = a;
result->composed.operator = operator;
@@ -180,18 +222,102 @@ cond_expr *build_composed_cond_expression(cond_expr *a, CondOpType operator, con
static void delete_cond_expr(cond_expr *expr)
{
- if (expr->is_simple)
+ switch (expr->type)
{
- free(expr->simple.variable);
- free(expr->simple.value);
+ case CET_NAMED:
+ free(expr->named);
+ break;
+
+ case CET_SIMPLE:
+ free(expr->simple.variable);
+ free(expr->simple.value);
+ break;
+
+ case CET_COMPOSED:
+ delete_cond_expr(expr->composed.a);
+ delete_cond_expr(expr->composed.b);
+ break;
+
}
- else
+
+ free(expr);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : expr = expression simple ou composée à transposer. *
+* bits = gestionnaire des bits d'encodage. *
+* list = liste de l'ensemble des fonctions de conversion. *
+* *
+* Description : Marque les éléments de conditions comme utilisés. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool mark_cond_expr(const cond_expr *expr, const coding_bits *bits, const conv_list *list)
+{
+ bool result; /* Bilan de marquage à renvoyer*/
+
+ result = false;
+
+ bool mark_cond_expr_by_name(const char *name)
+ {
+ conv_func *conv; /* Conversion utilisée */
+ bool status; /* Bilan d'un marquage */
+ raw_bitfield *bf; /* Champ de bits utilisé */
+
+ conv = find_named_conv_in_list(list, name);
+
+ if (conv != NULL)
+ status = mark_conv_func(conv, true, bits, list);
+
+ else
+ {
+ bf = find_named_field_in_bits(bits, name);
+
+ if (bf != NULL)
+ {
+ mark_raw_bitfield_as_used(bf);
+ status = true;
+ }
+
+ else status = false;
+
+ }
+
+
+ printf("=== USE '%s' : %d\n", name, status);
+
+ if (!status)
+ fprintf(stderr, "Error: nothing defined for the requested variable '%s'.\n", name);
+
+ return status;
+
+ }
+
+ switch (expr->type)
{
- delete_cond_expr(expr->composed.a);
- delete_cond_expr(expr->composed.b);
+ case CET_NAMED:
+ result = mark_cond_expr_by_name(expr->named);
+ break;
+
+ case CET_SIMPLE:
+ result = mark_cond_expr_by_name(expr->simple.variable);
+ break;
+
+ case CET_COMPOSED:
+ result = mark_cond_expr(expr->composed.a, bits, list);
+ result &= mark_cond_expr(expr->composed.b, bits, list);
+ break;
+
}
- free(expr);
+ return result;
}
@@ -201,6 +327,7 @@ static void delete_cond_expr(cond_expr *expr)
* Paramètres : expr = expression simple ou composée à transposer. *
* fd = descripteur d'un flux ouvert en écriture. *
* bits = gestionnaire des bits d'encodage. *
+* list = liste de l'ensemble des fonctions de conversion. *
* *
* Description : Traduit en code une expression de condition. *
* *
@@ -210,9 +337,10 @@ static void delete_cond_expr(cond_expr *expr)
* *
******************************************************************************/
-static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits)
+static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bits, const conv_list *list)
{
bool result; /* Bilan à renvoyer */
+ const conv_func *conv; /* Conversion utilisée */
const raw_bitfield *bf; /* Champ de bits de définition */
unsigned int provided; /* Nombre de bits fournis */
@@ -220,67 +348,91 @@ static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bi
dprintf(fd, "(");
- if (expr->is_simple)
+ switch (expr->type)
{
- bf = find_named_field_in_bits(bits, expr->simple.variable);
- if (bf == NULL)
- {
- fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n", expr->simple.variable);
- result = false;
- goto wce_exit;
- }
+ case CET_NAMED:
- if (expr->simple.is_binary)
- provided = strlen(expr->simple.value);
- else
- provided = 4 * strlen(expr->simple.value);
+ conv = find_named_conv_in_list(list, expr->named);
- if (get_raw_bitfield_length(bf) != provided)
- {
- fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %u).\n",
- expr->simple.variable, get_raw_bitfield_length(bf), provided);
- result = false;
- goto wce_exit;
- }
+ if (conv != NULL)
+ dprintf(fd, "val_%s", expr->named);
- dprintf(fd, "raw_%s", expr->simple.variable);
+ else
+ {
+ bf = find_named_field_in_bits(bits, expr->named);
+ assert(bf != NULL);
- switch (expr->simple.comp)
- {
- case CCT_EQUAL:
- dprintf(fd, " == ");
- break;
- case CCT_DIFF:
- dprintf(fd, " != ");
- break;
- case CCT_AND:
- dprintf(fd, " & ");
- break;
- }
+ dprintf(fd, "raw_%s", expr->named);
- if (expr->simple.is_binary)
- dprintf(fd, "b%s", expr->simple.value);
- else
- dprintf(fd, "0x%s", expr->simple.value);
+ }
- }
- else
- {
- result = write_cond_expr(expr->composed.a, fd, bits);
- if (!result) goto wce_exit;
+ break;
- switch (expr->composed.operator)
- {
- case COT_AND:
- dprintf(fd, " && ");
- break;
- case COT_OR:
- dprintf(fd, " || ");
- break;
- }
+ case CET_SIMPLE:
+
+ bf = find_named_field_in_bits(bits, expr->simple.variable);
+ if (bf == NULL)
+ {
+ fprintf(stderr, "Error: no bitfield defined the requested variable '%s'.\n",
+ expr->simple.variable);
+ result = false;
+ goto wce_exit;
+ }
+
+ if (expr->simple.is_binary)
+ provided = strlen(expr->simple.value);
+ else
+ provided = 4 * strlen(expr->simple.value);
+
+ if (get_raw_bitfield_length(bf) != provided)
+ {
+ fprintf(stderr, "Error: variable '%s' and provided value sizes do not match (%u vs %u).\n",
+ expr->simple.variable, get_raw_bitfield_length(bf), provided);
+ result = false;
+ goto wce_exit;
+ }
+
+ dprintf(fd, "raw_%s", expr->simple.variable);
+
+ switch (expr->simple.comp)
+ {
+ case CCT_EQUAL:
+ dprintf(fd, " == ");
+ break;
+ case CCT_DIFF:
+ dprintf(fd, " != ");
+ break;
+ case CCT_AND:
+ dprintf(fd, " & ");
+ break;
+ }
- result = write_cond_expr(expr->composed.b, fd, bits);
- if (!result) goto wce_exit;
+ if (expr->simple.is_binary)
+ dprintf(fd, "b%s", expr->simple.value);
+ else
+ dprintf(fd, "0x%s", expr->simple.value);
+
+ break;
+
+ case CET_COMPOSED:
+
+ result = write_cond_expr(expr->composed.a, fd, bits, list);
+ if (!result) goto wce_exit;
+
+ switch (expr->composed.operator)
+ {
+ case COT_AND:
+ dprintf(fd, " && ");
+ break;
+ case COT_OR:
+ dprintf(fd, " || ");
+ break;
+ }
+
+ result = write_cond_expr(expr->composed.b, fd, bits, list);
+ if (!result) goto wce_exit;
+
+ break;
}
@@ -403,6 +555,54 @@ void register_conditional_rule(decoding_rules *rules, cond_expr *expr, const rul
/******************************************************************************
* *
+* Paramètres : rules = ensemble de règles à manipuler. *
+* bits = gestionnaire des bits d'encodage. *
+* list = liste de l'ensemble des fonctions de conversion. *
+* *
+* Description : Marque les éléments de règles effectivement utilisés. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool mark_decoding_rules(const decoding_rules *rules, const coding_bits *bits, const conv_list *list)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+ const extra_rule *rule; /* Règle en cours d'écriture */
+
+ result = true;
+
+ for (i = 0; i < rules->extra_count && result; i++)
+ {
+ rule = &rules->extra[i];
+
+ if (rule->expr != NULL)
+ result = mark_cond_expr(rule->expr, bits, list);
+
+ switch (rule->action.type)
+ {
+ case CAT_CALL:
+ case CAT_CHECKED_CALL:
+ result &= ensure_arg_list_content_fully_marked(rule->action.args, bits, list);
+ break;
+
+ default:
+ break;
+
+ }
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : rules = ensemble de règles à consulter. *
* top = indique si l'écriture se fait au plus haut niveau. *
* filter = filtre sur les règles à effectivement imprimer. *
@@ -458,7 +658,7 @@ bool write_decoding_rules(decoding_rules *rules, bool top, CondActionType filter
dprintf(fd, "\tif ");
- result = write_cond_expr(rule->expr, fd, bits);
+ result = write_cond_expr(rule->expr, fd, bits, list);
if (!result) break;
dprintf(fd, "\n");
diff --git a/tools/d2c/rules/manager.h b/tools/d2c/rules/manager.h
index 7106c32..347b330 100644
--- a/tools/d2c/rules/manager.h
+++ b/tools/d2c/rules/manager.h
@@ -56,6 +56,9 @@ typedef enum _CondOpType
typedef struct _cond_expr cond_expr;
+/* Crée une expression conditionnelle reposant sur une variable. */
+cond_expr *build_named_cond_expression(char *);
+
/* Crée une expression conditionnelle simple. */
cond_expr *build_simple_cond_expression(char *, CondCompType, char *, bool);
@@ -87,7 +90,7 @@ typedef struct _rule_action
/* CAT_SEE */
char *details; /* Eventuel complément d'info. */
- /* CAT_CALL */
+ /* CAT_CALL / CAT_CHECKED_CALL */
struct
{
char *callee; /* Fonction appelée */
@@ -112,6 +115,9 @@ void delete_decoding_rules(decoding_rules *);
/* Ajoute une règle complète à la définition d'un codage. */
void register_conditional_rule(decoding_rules *, cond_expr *, const rule_action *);
+/* Marque les éléments de règles effectivement utilisés. */
+bool mark_decoding_rules(const decoding_rules *, const coding_bits *, const conv_list *);
+
/* Traduit en code les éventuelles règles présentes. */
bool write_decoding_rules(decoding_rules *, bool, CondActionType, int, const char *, const char *, const coding_bits *, const conv_list *, const pre_processor *, bool *);
diff --git a/tools/d2c/spec.c b/tools/d2c/spec.c
index 0a47b72..1d91fed 100644
--- a/tools/d2c/spec.c
+++ b/tools/d2c/spec.c
@@ -300,13 +300,15 @@ decoding_rules *get_rules_in_encoding_spec(const encoding_spec *spec)
bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *arch, const char *subarch, const char *ins, const char *details, unsigned int wide, const pre_processor *pp)
{
bool result; /* Bilan à retourner */
+ bool bad_exit; /* Ajout d'une sortie d'échec ?*/
char *keyword; /* Mot clef appelable en code */
bool quick_exit; /* Inclusion de sortie rapide ?*/
- bool bad_exit; /* Ajout d'une sortie d'échec ?*/
const char *new_ins; /* Nouvelle définition de nom */
result = true;
+ bad_exit = false;
+
keyword = make_callable(ins, false);
dprintf(fd, "\tGArchInstruction *%s_decode_%s%s_%s%u(uint%u_t _raw)\n",
@@ -320,8 +322,12 @@ bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *a
result &= mark_syntax_items(spec->syntax, spec->bits, spec->conversions);
+ result &= mark_decoding_rules(spec->rules, spec->bits, spec->conversions);
+
result &= declare_used_bits_fields(spec->bits, fd, wide);
+ result &= declare_used_intermediate_conversions(spec->conversions, fd, spec->bits, pp, wide);
+
result &= declare_syntax_items(spec->syntax, fd, spec->bits, spec->conversions, wide);
dprintf(fd, "\n");
@@ -336,7 +342,7 @@ bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *a
result &= define_used_bits_fields(spec->bits, fd);
- dprintf(fd, "\n");
+ result &= define_used_intermediate_conversions(spec->conversions, fd, arch, spec->bits, pp, &bad_exit);
/* Inclusion des éventuelles règles */
@@ -368,8 +374,6 @@ bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *a
/* Création des opérandes */
- bad_exit = false;
-
result &= define_syntax_items(spec->syntax, fd, arch, spec->bits, spec->conversions, pp, &bad_exit);
/* Conclusion de la procédure */
diff --git a/tools/d2c/syntax/manager.c b/tools/d2c/syntax/manager.c
index ae2a71b..02d9813 100644
--- a/tools/d2c/syntax/manager.c
+++ b/tools/d2c/syntax/manager.c
@@ -201,7 +201,7 @@ bool mark_syntax_items(const asm_syntax *syntax, const coding_bits *bits, const
result = false;
}
- result = mark_conv_func(func, bits, list);
+ result = mark_conv_func(func, false, bits, list);
}
@@ -232,7 +232,6 @@ bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *b
bool has_operand; /* Présence d'un opérande */
size_t i; /* Boucle de parcours */
syntax_item *item; /* Lien vers un opérande */
- conv_func *func; /* Fonction de conversion */
result = true;
@@ -245,15 +244,6 @@ bool declare_syntax_items(const asm_syntax *syntax, int fd, const coding_bits *b
has_operand |= (item->impact == SIT_EXT_OPERAND);
- func = find_named_conv_in_list(list, item->name);
- if (func == NULL)
- {
- fprintf(stderr, "Error: expected conversion for '%s'.\n", item->name);
- result = false;
- }
-
- result &= declare_conv_func(func, fd, bits, list, wide);
-
}
if (has_operand)
@@ -329,14 +319,22 @@ bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, con
{
case SIT_KEYWORD:
+ /**
+ * TODO : à faire évoluer vers extend...
+ */
+ //_exit(123);
+
+ // rev_A88146
+ /*
if (i > 0)
dprintf(fd, "\t\tg_arch_instruction_append_suffix(instr, \"%s\");\n", item->name);
else
continue;
+ */
break;
- case SIT_INT_OPERAND:
+ case SIT_INT_OPERAND: // A supprimer
case SIT_EXT_OPERAND:
internal = (item->impact == SIT_INT_OPERAND);
@@ -350,17 +348,9 @@ bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, con
/* Appel proprement dit */
- result &= define_conv_func(func, true, internal, fd, arch, bits, list, pp);
- if (!result) break;
-
- /* Raccordement : propriété ou opérande ? */
-
- if (internal)
- dprintf(fd, "\t\t\tgoto bad_exit;\n");
-
- else
+ if (is_conv_func_already_defined(func))
{
- dprintf(fd, "\t\tif (op == NULL) goto bad_exit;\n");
+ dprintf(fd, "\t\top = val_%s;\n", item->name);
dprintf(fd, "\n");
@@ -371,6 +361,35 @@ bool define_syntax_items(const asm_syntax *syntax, int fd, const char *arch, con
}
+ else
+ {
+ result &= define_conv_func(func, true, internal, fd, arch, bits, list, pp, exit);
+ if (!result) break;
+
+ /* Raccordement : propriété ou opérande ? */
+
+ if (internal)
+ {
+ dprintf(fd, "\t\t\tgoto bad_exit;\n");
+ *exit = true;
+ }
+
+ else
+ {
+ dprintf(fd, "\t\tif (op == NULL) goto bad_exit;\n");
+ *exit = true;
+
+ dprintf(fd, "\n");
+
+ if (item->flags & SIF_DECIMAL)
+ dprintf(fd, "\t\tg_imm_operand_set_default_display(G_IMM_OPERAND(op), IOD_DEC);\n");
+
+ dprintf(fd, "\t\tg_arch_instruction_attach_extra_operand(instr, op);\n");
+
+ }
+
+ }
+
*exit = true;
break;
diff --git a/tools/d2c/tokens.l b/tools/d2c/tokens.l
index 1e4b7b0..220e5d6 100644
--- a/tools/d2c/tokens.l
+++ b/tools/d2c/tokens.l
@@ -45,7 +45,7 @@
"@title" { BEGIN(ins_name); return TITLE; }
-<ins_name>[ ][A-Za-z-]+ { yylvalp->string = strdup(yytext + 1); BEGIN(try_details); return INS_NAME; }
+<ins_name>[ ][A-Za-z0-9-]+ { yylvalp->string = strdup(yytext + 1); BEGIN(try_details); return INS_NAME; }
<try_details>[ ,/-] { BEGIN(ins_details); yylvalp->character = yytext[0]; return INS_SEP; }
<try_details>[\n] { BEGIN(INITIAL); }
@@ -53,6 +53,8 @@
<ins_details>[\n] { BEGIN(INITIAL); }
+"@desc" { yy_push_state(raw_line); return DESC; }
+
"@encoding" { BEGIN(encoding); return ENCODING; }