summaryrefslogtreecommitdiff
path: root/src/decomp
diff options
context:
space:
mode:
Diffstat (limited to 'src/decomp')
-rw-r--r--src/decomp/context.c55
-rw-r--r--src/decomp/context.h5
-rw-r--r--src/decomp/expr/pseudo.c30
-rw-r--r--src/decomp/expr/pseudo.h3
4 files changed, 91 insertions, 2 deletions
diff --git a/src/decomp/context.c b/src/decomp/context.c
index 7fe6937..6440c56 100644
--- a/src/decomp/context.c
+++ b/src/decomp/context.c
@@ -24,6 +24,14 @@
#include "context.h"
+#include <malloc.h>
+
+
+#include "expr/pseudo.h"
+#include "../arch/operand.h"
+#include "../glibext/gnhash.h"
+
+
/* Définition d'une context décompilée (instance) */
struct _GDecContext
@@ -32,6 +40,12 @@ struct _GDecContext
vmpa_t max; /* Première adresse à écarter */
+ GHashTable *machine; /* Correspondance reg./pseudo */
+ GHashTable *ssa; /* Remplacement des pseudos */
+
+ GDecInstruction **pseudos; /* Liste des pseudos-registre */
+ size_t count; /* Taille de cette liste */
+
};
@@ -87,6 +101,8 @@ static void g_dec_context_class_init(GDecContextClass *klass)
static void g_dec_context_init(GDecContext *ctx)
{
+ ctx->machine = g_hash_table_new(g_constant_hash, (GEqualFunc)g_arch_operand_compare);
+ ctx->ssa = g_hash_table_new(NULL, NULL);
}
@@ -151,3 +167,42 @@ void g_dec_context_set_max_address(GDecContext *ctx, vmpa_t max)
ctx->max = max;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : ctx = instance à consulter, voire mettre à jour. *
+* operand = opérande représentant un registre quelconque. *
+* *
+* Description : Convertit un registre machine en un pseudo-registre. *
+* *
+* Retour : Pseudo-registre, existant ou non, prêt à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GDecInstruction *g_dec_context_convert_register(GDecContext *ctx, gpointer operand)
+{
+ GDecInstruction *result; /* Instance à retourner */
+ gpointer *found; /* Pseudo-registre trouvé */
+
+ found = g_hash_table_lookup(ctx->machine, operand);
+
+ if (found != NULL) result = G_DEC_INSTRUCTION(found);
+ else
+ {
+ result = g_pseudo_register_new();
+ g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->count);
+
+ g_hash_table_insert(ctx->machine, operand, result);
+
+ ctx->pseudos = (GDecInstruction **)realloc(ctx->pseudos,
+ ++ctx->count * sizeof(GDecInstruction *));
+ ctx->pseudos[ctx->count - 1] = result;
+
+ }
+
+ return result;
+
+}
diff --git a/src/decomp/context.h b/src/decomp/context.h
index 76105e6..926a372 100644
--- a/src/decomp/context.h
+++ b/src/decomp/context.h
@@ -28,7 +28,7 @@
#include <glib-object.h>
-#include "expr/pseudo.h"
+#include "instruction.h"
#include "../arch/archbase.h"
@@ -61,6 +61,9 @@ vmpa_t g_dec_context_get_max_address(const GDecContext *);
/* Définit l'adresse où la décompilation n'est plus souhaitée. */
void g_dec_context_set_max_address(GDecContext *, vmpa_t);
+/* Convertit un registre machine en un pseudo-registre. */
+GDecInstruction *g_dec_context_convert_register(GDecContext *, gpointer);
+
#endif /* _DECOMP_CONTEXT_H */
diff --git a/src/decomp/expr/pseudo.c b/src/decomp/expr/pseudo.c
index 393f32c..abfcd4d 100644
--- a/src/decomp/expr/pseudo.c
+++ b/src/decomp/expr/pseudo.c
@@ -24,6 +24,10 @@
#include "pseudo.h"
+#include <stdio.h>
+#include <string.h>
+
+
#include "../expression-int.h"
@@ -33,6 +37,8 @@ struct _GPseudoRegister
{
GDecExpression parent; /* A laisser en premier */
+ size_t index; /* Position dans l'ensemble */
+
};
@@ -141,8 +147,30 @@ GDecInstruction *g_pseudo_register_new(void)
static void g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output)
{
+ char label[32];
+
+ snprintf(label, 32, "var%d", reg->index);
+
+ g_buffer_line_insert_text(line, BLC_ASSEMBLY, label, strlen(label), RTT_RAW);
- g_buffer_line_insert_text(line, BLC_ASSEMBLY, "varX", 4, RTT_RAW);
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = expression représentant un pseudo-registre à traiter.*
+* index = indice à associer au pseudo-registre. *
+* *
+* Description : Définit un indice unique pour un pseudo-registre donné. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+void g_pseudo_register_set_index(GPseudoRegister *reg, size_t index)
+{
+ reg->index = index;
}
diff --git a/src/decomp/expr/pseudo.h b/src/decomp/expr/pseudo.h
index 9734625..95612a9 100644
--- a/src/decomp/expr/pseudo.h
+++ b/src/decomp/expr/pseudo.h
@@ -54,6 +54,9 @@ GType g_pseudo_register_get_type(void);
/* Assigne le contenu d'une expression dans une autre. */
GDecInstruction *g_pseudo_register_new(void);
+/* Définit un indice unique pour un pseudo-registre donné. */
+void g_pseudo_register_set_index(GPseudoRegister *, size_t);
+
#endif /* _DECOMP_EXPR_PSEUDO_H */