summaryrefslogtreecommitdiff
path: root/tools/d2c/rules.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/d2c/rules.c')
-rw-r--r--tools/d2c/rules.c75
1 files changed, 61 insertions, 14 deletions
diff --git a/tools/d2c/rules.c b/tools/d2c/rules.c
index 6f2e075..3101727 100644
--- a/tools/d2c/rules.c
+++ b/tools/d2c/rules.c
@@ -48,7 +48,9 @@ struct _cond_expr
{
char *variable; /* Variable manipulée */
CondCompType comp; /* Type de comparaison */
- char *bvalue; /* Valeur binaire comparée */
+ char *value; /* Valeur binaire comparée */
+
+ bool is_binary; /* Binaire ou hexadécimal */
} simple;
@@ -101,9 +103,10 @@ struct _decoding_rules
/******************************************************************************
* *
-* Paramètres : variable = désignation de la variable à manipuler. *
-* comp = type de comparaison à utiliser. *
-* bvalue = valeur binaire à comparer. *
+* 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. *
* *
* Description : Crée une expression conditionnelle simple. *
* *
@@ -113,7 +116,7 @@ struct _decoding_rules
* *
******************************************************************************/
-cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char *bvalue)
+cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char *value, bool is_binary)
{
cond_expr *result; /* Structure à retourner */
@@ -123,7 +126,9 @@ cond_expr *build_simple_cond_expression(char *variable, CondCompType comp, char
result->simple.variable = make_string_lower(variable);
result->simple.comp = comp;
- result->simple.bvalue = bvalue;
+ result->simple.value = value;
+
+ result->simple.is_binary = is_binary;
return result;
@@ -178,7 +183,7 @@ static void delete_cond_expr(cond_expr *expr)
if (expr->is_simple)
{
free(expr->simple.variable);
- free(expr->simple.bvalue);
+ free(expr->simple.value);
}
else
{
@@ -209,6 +214,7 @@ static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bi
{
bool result; /* Bilan à renvoyer */
const raw_bitfield *bf; /* Champ de bits de définition */
+ unsigned int provided; /* Nombre de bits fournis */
result = true;
@@ -224,10 +230,15 @@ static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bi
goto wce_exit;
}
- if (get_raw_bitfield_length(bf) != strlen(expr->simple.bvalue))
+ 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 %zu).\n",
- expr->simple.variable, get_raw_bitfield_length(bf), strlen(expr->simple.bvalue));
+ 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;
}
@@ -242,9 +253,15 @@ static bool write_cond_expr(const cond_expr *expr, int fd, const coding_bits *bi
case CCT_DIFF:
dprintf(fd, " != ");
break;
+ case CCT_AND:
+ dprintf(fd, " & ");
+ break;
}
- dprintf(fd, "b%s", expr->simple.bvalue);
+ if (expr->simple.is_binary)
+ dprintf(fd, "b%s", expr->simple.value);
+ else
+ dprintf(fd, "0x%s", expr->simple.value);
}
else
@@ -339,6 +356,7 @@ void delete_decoding_rules(decoding_rules *rules)
break;
case CAT_CALL:
+ case CAT_CHECKED_CALL:
free(rule->action.callee);
delete_arg_list(rule->action.args);
break;
@@ -406,8 +424,9 @@ void register_conditional_rule(decoding_rules *rules, cond_expr *expr, const rul
bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd, const char *arch, const char *subarch, const coding_bits *bits, const conv_list *list, const pre_processor *pp, bool *exit)
{
bool result; /* Bilan à remonter */
- const extra_rule *rule; /* Règle en cours d'écriture */
size_t i; /* Boucle de parcours */
+ const extra_rule *rule; /* Règle en cours d'écriture */
+ bool multi_lines; /* Nécessite des accolades */
const char *callable; /* Fonction à appeler */
result = true;
@@ -419,6 +438,18 @@ bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd,
if (rule->action.type != filter)
continue;
+ switch (rule->action.type)
+ {
+ case CAT_CALL:
+ multi_lines = false;
+ break;
+
+ default:
+ multi_lines = true;
+ break;
+
+ }
+
if (rule->expr != NULL)
{
dprintf(fd, "\t\tif ");
@@ -427,7 +458,9 @@ bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd,
if (!result) break;
dprintf(fd, "\n");
- dprintf(fd, "\t\t{\n");
+
+ if (multi_lines)
+ dprintf(fd, "\t\t{\n");
}
@@ -460,6 +493,20 @@ bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd,
result = call_instr_func(callable, rule->action.args, fd, bits, list, pp);
+ break;
+
+ case CAT_CHECKED_CALL:
+
+ callable = find_macro(pp, rule->action.callee);
+
+ if (callable == NULL)
+ callable = rule->action.callee;
+
+ if (rule->expr != NULL)
+ dprintf(fd, "\t");
+
+ result = checked_call_instr_func(callable, rule->action.args, fd, bits, list, pp);
+
if (rule->expr != NULL)
dprintf(fd, "\t");
@@ -470,7 +517,7 @@ bool write_decoding_rules(decoding_rules *rules, CondActionType filter, int fd,
}
- if (rule->expr != NULL)
+ if (rule->expr != NULL && multi_lines)
dprintf(fd, "\t\t}\n");
dprintf(fd, "\n");