summaryrefslogtreecommitdiff
path: root/tools/d2c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/d2c')
-rw-r--r--tools/d2c/args.c29
-rw-r--r--tools/d2c/args.h1
-rw-r--r--tools/d2c/d2c_gram.y22
-rw-r--r--tools/d2c/d2c_tok.l32
-rw-r--r--tools/d2c/qckcall.c119
-rw-r--r--tools/d2c/qckcall.h3
-rw-r--r--tools/d2c/rules.c75
-rw-r--r--tools/d2c/rules.h8
-rw-r--r--tools/d2c/spec.c3
9 files changed, 225 insertions, 67 deletions
diff --git a/tools/d2c/args.c b/tools/d2c/args.c
index 616873b..1a2c287 100644
--- a/tools/d2c/args.c
+++ b/tools/d2c/args.c
@@ -73,7 +73,12 @@ struct _arg_expr_t
union
{
/* CET_NAME */
- char *name; /* Désignation de variable */
+ struct
+ {
+ char *original; /* Désignation non transformée */
+ char *name; /* Désignation de variable */
+
+ };
/* CET_NUMBER */
unsigned long number; /* Valeur durablement définie */
@@ -83,6 +88,7 @@ struct _arg_expr_t
{
char **comp_items; /* Elements à agréger */
size_t comp_count; /* Quantité de ces éléments */
+
};
/* CET_UNARY */
@@ -156,6 +162,7 @@ arg_expr_t *build_arg_expr_from_name(char *name)
result->type = CET_NAME;
+ result->original = strdup(name);
result->name = make_string_lower(name);
return result;
@@ -327,6 +334,7 @@ void delete_arg_expr(arg_expr_t *expr)
switch (expr->type)
{
case CET_NAME:
+ free(expr->original);
free(expr->name);
break;
@@ -392,6 +400,11 @@ bool compute_arg_expr_size(const arg_expr_t *expr, const coding_bits *bits, cons
result = compute_conv_func_size(func, bits, list, size);
}
+ /**
+ * On autorise le passage de constante inconnue par d2c mais valable pour gcc.
+ */
+ else result = true;
+
break;
case CET_COMPOSED:
@@ -590,7 +603,8 @@ bool ensure_arg_expr_content_fully_marked(arg_expr_t *expr, const coding_bits *b
switch (sub->type)
{
case CET_NAME:
- result = mark_by_name(bits, lst, sub->name);
+ /* result = */mark_by_name(bits, lst, sub->name);
+ result = true;
break;
case CET_COMPOSED:
@@ -678,7 +692,8 @@ 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(f, bits, lst, *wide, sub->name);
+ result = true;
break;
case CET_COMPOSED:
@@ -762,7 +777,8 @@ bool ensure_arg_expr_content_fully_defined(arg_expr_t *expr, int fd, const char
switch (sub->type)
{
case CET_NAME:
- result = define_by_name(f, bits, lst, info, sub->name);
+ /* result = */define_by_name(f, bits, lst, info, sub->name);
+ result = true;
break;
case CET_COMPOSED:
@@ -824,7 +840,7 @@ bool define_arg_expr(const arg_expr_t *expr, int fd, const coding_bits *bits, co
case CET_NAME:
if (!find_var_by_name(bits, list, expr->name, &field, &func))
- result = false;
+ dprintf(fd, "%s", expr->original);
else
{
@@ -926,6 +942,9 @@ bool define_arg_expr(const arg_expr_t *expr, int fd, const coding_bits *bits, co
switch (expr->bin_op)
{
+ case CBO_AND:
+ dprintf(fd, " & ");
+ break;
case CBO_EOR:
dprintf(fd, " ^ ");
break;
diff --git a/tools/d2c/args.h b/tools/d2c/args.h
index 0ad022e..d5855f4 100644
--- a/tools/d2c/args.h
+++ b/tools/d2c/args.h
@@ -49,6 +49,7 @@ typedef enum _ConvUnaryOperation
/* Types d'opérations binaires */
typedef enum _ConvBinaryOperation
{
+ CBO_AND, /* Et logique */
CBO_EOR, /* Ou exclusif (booléen) */
CBO_COUNT
diff --git a/tools/d2c/d2c_gram.y b/tools/d2c/d2c_gram.y
index 9e1e034..5d83930 100644
--- a/tools/d2c/d2c_gram.y
+++ b/tools/d2c/d2c_gram.y
@@ -143,11 +143,11 @@ struct action_tmp
%token SYNTAX OPERAND_NAME OPERAND_INTERNAL OPERAND_VISIBLE
-%token CONV EQ OP COMMA CP NOT EOR COLON
+%token CONV EQ OP COMMA CP NOT AND_LOG EOR COLON
%token HOOKS
-%token RULES IF EXPR_START EQUAL BINVAL IMMVAL EXPR_END AND THEN SEE CALL UNPREDICTABLE
+%token RULES IF EXPR_START EQUAL BINVAL HEXVAL EXPR_END AND THEN SEE CALL CHK_CALL UNPREDICTABLE
%type <string> COPYRIGHT INS_NAME
@@ -170,7 +170,7 @@ struct action_tmp
%type <string> arg_field
%type <expr> rule_cond
-%type <string> BINVAL IMMVAL
+%type <string> BINVAL HEXVAL
%type <raction> action
@@ -248,7 +248,8 @@ arg_expr : NAME { $$ = build_arg_expr_from_n
arg_expr_un_op : NOT { $$ = CUO_NOT; }
-arg_expr_bin_op : EOR { $$ = CBO_EOR; }
+arg_expr_bin_op : AND_LOG { $$ = CBO_AND; }
+ | EOR { $$ = CBO_EOR; }
arg_composed : arg_field COLON arg_field { $$ = build_composed_arg_expr($1, $3); }
| arg_composed COLON arg_field { $$ = extend_composed_arg_expr($1, $3); }
@@ -273,14 +274,17 @@ rules_list : /* empty */
rule : IF EXPR_START rule_cond EXPR_END THEN action { add_conditional_rule_to_coder(coder, $3, &$6); }
| action { add_conditional_rule_to_coder(coder, NULL, &$1); }
-rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3); }
- | NAME EQUAL IMMVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3); }
+rule_cond : 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); }
| EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END
{ $$ = build_composed_cond_expression($2, COT_AND, $6); }
-action : SEE INS_DETAILS { $$.type = CAT_SEE; $$.details = make_callable($2, false); }
- | UNPREDICTABLE { $$.type = CAT_UNPREDICTABLE; }
- | CALL NAME OP arg_list CP { $$.type = CAT_CALL; $$.callee = $2; $$.args = $4; }
+action : SEE INS_DETAILS { $$.type = CAT_SEE; $$.details = make_callable($2, false); }
+ | UNPREDICTABLE { $$.type = CAT_UNPREDICTABLE; }
+ | CALL NAME OP arg_list CP { $$.type = CAT_CALL; $$.callee = $2; $$.args = $4; }
+ | CHK_CALL NAME OP arg_list CP { $$.type = CAT_CHECKED_CALL; $$.callee = $2; $$.args = $4; }
%%
diff --git a/tools/d2c/d2c_tok.l b/tools/d2c/d2c_tok.l
index 9689b59..08562ce 100644
--- a/tools/d2c/d2c_tok.l
+++ b/tools/d2c/d2c_tok.l
@@ -39,7 +39,7 @@ void free_flex_memory(void) ;
%x hooks_begin hooks_content
-%x rules_begin rules_content rules_cond rules_cond_binval rules_action rules_action_see rules_action_call
+%x rules_begin rules_content rules_cond rules_cond_binval rules_cond_hexval rules_action rules_action_see rules_action_call
%%
@@ -84,9 +84,9 @@ void free_flex_memory(void) ;
<encoding_content>"@half" { BEGIN(encoding_bits); return HALF; }
<encoding_content>"@word" { BEGIN(encoding_bits); return WORD; }
-<encoding_bits>" " { }
-<encoding_bits>"\n" { BEGIN(encoding_content); }
-<encoding_bits>[A-Za-z][A-Za-z0-9_]* { d2c_lval.string = strdup(yytext); return NAME; }
+<encoding_bits>" " { }
+<encoding_bits>"\n" { BEGIN(encoding_content); }
+<encoding_bits>[A-Za-z_][A-Za-z0-9__]* { d2c_lval.string = strdup(yytext); return NAME; }
<encoding_bits>"(" { BEGIN(encoding_bits_size); }
<encoding_bits_size>[0-9]+ { d2c_lval.integer = atoi(yytext); return SIZE; }
@@ -135,8 +135,9 @@ void free_flex_memory(void) ;
-<conv_arg>[A-Za-z][A-Za-z0-9_]* {
+<conv_arg>[A-Za-z_][A-Za-z0-9_]* {
if (strcmp(yytext, "NOT") == 0) return NOT;
+ else if (strcmp(yytext, "AND") == 0) return AND_LOG;
else if (strcmp(yytext, "EOR") == 0) return EOR;
else
{
@@ -161,8 +162,9 @@ void free_flex_memory(void) ;
-<arg>[A-Za-z][A-Za-z0-9_]* {
+<arg>[A-Za-z_][A-Za-z0-9_]* {
if (strcmp(yytext, "NOT") == 0) return NOT;
+ else if (strcmp(yytext, "AND") == 0) return AND_LOG;
else if (strcmp(yytext, "EOR") == 0) return EOR;
else
{
@@ -203,18 +205,21 @@ void free_flex_memory(void) ;
<rules_content>"see " { BEGIN(rules_action_see); return SEE; }
<rules_content>"unpredictable" { return UNPREDICTABLE; }
<rules_content>"call" { BEGIN(rules_action_call); return CALL; }
+<rules_content>"chk_call" { BEGIN(rules_action_call); return CHK_CALL; }
<rules_content>"if" { BEGIN(rules_cond); return IF; }
<rules_cond>[ ]+ { }
<rules_cond>"(" { return EXPR_START; }
-<rules_cond>[A-Za-z][A-Za-z0-9]* { d2c_lval.string = strdup(yytext); return NAME; }
+<rules_cond>[A-Za-z_][A-Za-z0-9_]* { d2c_lval.string = strdup(yytext); return NAME; }
<rules_cond>"==" { return EQUAL; }
<rules_cond>"'" { BEGIN(rules_cond_binval); }
<rules_cond_binval>[01][01]* { d2c_lval.string = strdup(yytext); return BINVAL; }
<rules_cond_binval>"'" { BEGIN(rules_cond); }
-<rules_cond>[0-9][0-9]* { d2c_lval.string = strdup(yytext); return IMMVAL; }
+<rules_cond>"0x" { BEGIN(rules_cond_hexval); }
+<rules_cond_hexval>[0-9a-f][0-9a-f]* { d2c_lval.string = strdup(yytext); BEGIN(rules_cond); return HEXVAL; }
<rules_cond>")" { return EXPR_END; }
<rules_cond>"&&" { return AND; }
+<rules_cond>"&" { return AND_LOG; }
<rules_cond>";" { BEGIN(rules_action); return THEN; }
<rules_action>[ ]+ { }
@@ -224,11 +229,12 @@ void free_flex_memory(void) ;
<rules_action>"unpredictable" { BEGIN(rules_content); return UNPREDICTABLE; }
-<rules_action>"call" { BEGIN(rules_action_call); return CALL; }
-<rules_action_call>[\t ]+ { }
-<rules_action_call>[A-Za-z][A-Za-z0-9]* { d2c_lval.string = strdup(yytext); return NAME; }
-<rules_action_call>"(" { yy_push_state(arg); return OP; }
-<rules_action_call>[\n] { BEGIN(rules_content); }
+<rules_action>"call" { BEGIN(rules_action_call); return CALL; }
+<rules_action>"chk_call" { BEGIN(rules_action_call); return CHK_CALL; }
+<rules_action_call>[\t ]+ { }
+<rules_action_call>[A-Za-z_][A-Za-z0-9_]* { d2c_lval.string = strdup(yytext); return NAME; }
+<rules_action_call>"(" { yy_push_state(arg); return OP; }
+<rules_action_call>[\n] { BEGIN(rules_content); }
%%
diff --git a/tools/d2c/qckcall.c b/tools/d2c/qckcall.c
index ce9a0b2..e2e87d2 100644
--- a/tools/d2c/qckcall.c
+++ b/tools/d2c/qckcall.c
@@ -34,44 +34,44 @@
+/* Prépare au besoin la définition d'une macro de transtypage. */
+static char *build_cast_if_needed(const char *);
+
+
+
/******************************************************************************
* *
-* Paramètres : callee = fonction appelée à nomer. *
-* args = précise si la conversion est la dernière. *
-* 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. *
+* Paramètres : callee = fonction appelée à nommer. *
* *
-* Description : Réalise un appel à une fonction liée à une instruction. *
+* Description : Prépare au besoin la définition d'une macro de transtypage. *
* *
-* Retour : Bilan de l'opération. *
+* Retour : Macro de transtypage à libérer après usage ou NULL. *
* *
* Remarques : - *
* *
******************************************************************************/
-bool call_instr_func(const char *callee, const arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+static char *build_cast_if_needed(const char *callee)
{
- bool result; /* Bilan à remonter */
+ char *result; /* Macro à retourner */
regex_t preg; /* Expression régulière */
int ret; /* Bilan d'une manipulation */
regmatch_t pmatch[3]; /* Correspondances de chaînes */
size_t cmplen; /* Taille de comparaison */
- char *cast; /* Macro de transtypage */
+
+ result = NULL;
ret = regcomp(&preg, "(g_([a-z0-9]*)_instruction)", REG_EXTENDED);
if (ret != 0)
{
fprintf(stderr, "Internal error: bad regular expression.\n");
- return false;
+ return NULL;
}
ret = regexec(&preg, callee, sizeof(pmatch) / sizeof(regmatch_t), pmatch, 0);
if (ret == REG_NOMATCH)
{
fprintf(stderr, "Internal error: bad function for dealing wih instruction: '%s'.\n", callee);
- result = false;
goto cif_exit;
}
@@ -82,29 +82,102 @@ bool call_instr_func(const char *callee, const arg_list_t *args, int fd, const c
cmplen = MAX(strlen("arch"), pmatch[2].rm_eo - pmatch[2].rm_so);
- if (strncmp("arch", &callee[pmatch[2].rm_so], cmplen) == 0)
- dprintf(fd, "\t\tif (!%s(instr, ", callee);
+ if (strncmp("arch", &callee[pmatch[2].rm_so], cmplen) != 0)
+ {
+ result = strndup(&callee[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
+
+ result = make_string_upper(result);
+
+ }
+
+ cif_exit:
+
+ regfree(&preg);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : callee = fonction appelée à nommer. *
+* args = précise si la conversion est la dernière. *
+* 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. *
+* *
+* Description : Réalise un appel à une fonction liée à une instruction. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool call_instr_func(const char *callee, const arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+{
+ bool result; /* Bilan à remonter */
+ char *cast; /* Macro de transtypage */
+
+ cast = build_cast_if_needed(callee);
+
+ if (cast == NULL)
+ dprintf(fd, "\t\t%s(instr, ", callee);
else
{
- cast = strndup(&callee[pmatch[1].rm_so], pmatch[1].rm_eo - pmatch[1].rm_so);
+ dprintf(fd, "\t\t%s(%s(instr), ", callee, cast);
+ free(cast);
+ }
- cast = make_string_upper(cast);
+ result = define_arg_list(args, fd, bits, list);
- dprintf(fd, "\t\tif (!%s(%s(instr), ", callee, cast);
+ dprintf(fd, ");\n");
- free(cast);
+ return result;
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : callee = fonction appelée à nommer. *
+* args = précise si la conversion est la dernière. *
+* 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. *
+* *
+* Description : Réalise un appel à une fonction liée à une instruction. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool checked_call_instr_func(const char *callee, const arg_list_t *args, int fd, const coding_bits *bits, const conv_list *list, const pre_processor *pp)
+{
+ bool result; /* Bilan à remonter */
+ char *cast; /* Macro de transtypage */
+
+ cast = build_cast_if_needed(callee);
+
+ if (cast == NULL)
+ dprintf(fd, "\t\tif (!%s(instr, ", callee);
+
+ else
+ {
+ dprintf(fd, "\t\tif (!%s(%s(instr), ", callee, cast);
+ free(cast);
}
result = define_arg_list(args, fd, bits, list);
dprintf(fd, "))\n");
- cif_exit:
-
- regfree(&preg);
-
return result;
}
diff --git a/tools/d2c/qckcall.h b/tools/d2c/qckcall.h
index 59d4adc..42aa3db 100644
--- a/tools/d2c/qckcall.h
+++ b/tools/d2c/qckcall.h
@@ -39,6 +39,9 @@
/* Réalise un appel à une fonction liée à une instruction. */
bool call_instr_func(const char *, const arg_list_t *, int, const coding_bits *, const conv_list *, const pre_processor *);
+/* Réalise un appel à une fonction liée à une instruction. */
+bool checked_call_instr_func(const char *, const arg_list_t *, int, const coding_bits *, const conv_list *, const pre_processor *);
+
#endif /* _TOOLS_QCKCALL_H */
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");
diff --git a/tools/d2c/rules.h b/tools/d2c/rules.h
index 6344828..cac6a55 100644
--- a/tools/d2c/rules.h
+++ b/tools/d2c/rules.h
@@ -39,7 +39,8 @@
typedef enum _CondCompType
{
CCT_EQUAL, /* Egalité '==' */
- CCT_DIFF /* Différence '!=' */
+ CCT_DIFF, /* Différence '!=' */
+ CCT_AND /* Et logique '&' */
} CondCompType;
@@ -56,7 +57,7 @@ typedef struct _cond_expr cond_expr;
/* Crée une expression conditionnelle simple. */
-cond_expr *build_simple_cond_expression(char *, CondCompType, char *);
+cond_expr *build_simple_cond_expression(char *, CondCompType, char *, bool);
/* Crée une expression conditionnelle composée. */
cond_expr *build_composed_cond_expression(cond_expr *, CondOpType, cond_expr *);
@@ -71,7 +72,8 @@ typedef enum _CondActionType
{
CAT_SEE, /* Renvoi vers une instruction */
CAT_UNPREDICTABLE, /* Cas de figure improbable */
- CAT_CALL /* Appel à une fonction C */
+ CAT_CALL, /* Appel à une fonction C */
+ CAT_CHECKED_CALL /* Appel à une fonction C */
} CondActionType;
diff --git a/tools/d2c/spec.c b/tools/d2c/spec.c
index 9d4447d..7d65cab 100644
--- a/tools/d2c/spec.c
+++ b/tools/d2c/spec.c
@@ -324,6 +324,9 @@ bool write_encoding_spec_disass(const encoding_spec *spec, int fd, const char *a
result &= write_hook_functions(spec->hooks, fd);
+ result &= write_decoding_rules(spec->rules, CAT_CHECKED_CALL,
+ fd, arch, subarch, spec->bits, spec->conversions, pp, &exit);
+
result &= write_decoding_rules(spec->rules, CAT_CALL,
fd, arch, subarch, spec->bits, spec->conversions, pp, &exit);