summaryrefslogtreecommitdiff
path: root/tools/d2c/rules
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/d2c/rules
parent33aa90b022e7d711a733ca7eb62c0b285f974317 (diff)
Extended the compiler to transform all the new ARMv7 encoding definitions.
Diffstat (limited to 'tools/d2c/rules')
-rw-r--r--tools/d2c/rules/grammar.y3
-rw-r--r--tools/d2c/rules/manager.c330
-rw-r--r--tools/d2c/rules/manager.h8
3 files changed, 274 insertions, 67 deletions
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 *);