diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/d2c/args/grammar.y | 18 | ||||
-rw-r--r-- | tools/d2c/args/manager.c | 201 | ||||
-rw-r--r-- | tools/d2c/args/manager.h | 17 | ||||
-rw-r--r-- | tools/d2c/args/tokens.l | 7 | ||||
-rw-r--r-- | tools/d2c/bits/manager.c | 8 | ||||
-rw-r--r-- | tools/d2c/conv/manager.c | 154 | ||||
-rw-r--r-- | tools/d2c/conv/manager.h | 15 | ||||
-rw-r--r-- | tools/d2c/d2c.mk | 3 | ||||
-rwxr-xr-x | tools/d2c/d2c_genmakefile.sh | 11 | ||||
-rw-r--r-- | tools/d2c/grammar.y | 13 | ||||
-rw-r--r-- | tools/d2c/pproc.c | 53 | ||||
-rw-r--r-- | tools/d2c/pproc.h | 7 | ||||
-rw-r--r-- | tools/d2c/rules/grammar.y | 3 | ||||
-rw-r--r-- | tools/d2c/rules/manager.c | 330 | ||||
-rw-r--r-- | tools/d2c/rules/manager.h | 8 | ||||
-rw-r--r-- | tools/d2c/spec.c | 12 | ||||
-rw-r--r-- | tools/d2c/syntax/manager.c | 63 | ||||
-rw-r--r-- | tools/d2c/tokens.l | 4 |
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; } |