summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/operands/it.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/arm/v7/operands/it.c')
-rw-r--r--plugins/arm/v7/operands/it.c155
1 files changed, 135 insertions, 20 deletions
diff --git a/plugins/arm/v7/operands/it.c b/plugins/arm/v7/operands/it.c
index 54e15ed..46e1b4c 100644
--- a/plugins/arm/v7/operands/it.c
+++ b/plugins/arm/v7/operands/it.c
@@ -27,30 +27,55 @@
#include <assert.h>
-#include <arch/operand-int.h>
#include <common/sort.h>
-#include <gtkext/gtkblockdisplay.h>
+#include <core/columns.h>
+
+
+#include "../operand-int.h"
/* -------------------------- DEFINITION D'UN NOUVEAU TYPE -------------------------- */
-/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */
-struct _GArmV7ITCondOperand
+/* Informations glissées dans la structure GObject de GArchOperand */
+typedef struct _a7itcop_extra_data_t
{
- GArchOperand parent; /* Instance parente */
+ operand_extra_data_t parent; /* A laisser en premier */
ArmCondCode firstcond; /* Condition première */
uint8_t mask; /* Masque de l'interprétation */
+} a7itcop_extra_data_t;
+
+
+/* Définition d'un opérande organisant l'application d'une instruction IT (instance) */
+struct _GArmV7ITCondOperand
+{
+ GArmV7Operand parent; /* Instance parente */
+
};
+/**
+ * Accès aux informations éventuellement déportées.
+ */
+
+#if 1 //__SIZEOF_INT__ == __SIZEOF_LONG__
+
+# define GET_ARMV7_ITCOND_OP_EXTRA(op) ((a7itcop_extra_data_t *)&((GArchOperand *)op)->extra)
+
+#else
+
+# define GET_ARMV7_ITCOND_OP_EXTRA(op) GET_GOBJECT_EXTRA(G_OBJECT(op), a7itcop_extra_data_t)
+
+#endif
+
+
/* Définition d'un opérande organisant l'application d'une instruction IT (classe) */
struct _GArmV7ITCondOperandClass
{
- GArchOperandClass parent; /* Classe parente */
+ GArmV7OperandClass parent; /* Classe parente */
};
@@ -78,6 +103,9 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *, const GAr
/* Traduit un opérande en version humainement lisible. */
static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *, GBufferLine *);
+/* Fournit l'empreinte d'un candidat à une centralisation. */
+static guint g_armv7_itcond_operand_hash(const GArmV7ITCondOperand *, bool);
+
/* Charge un contenu depuis une mémoire tampon. */
static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *, GObjectStorage *, packed_buffer_t *);
@@ -92,7 +120,7 @@ static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *, GObjectStorage *
/* Indique le type défini par la GLib pour l'application d'une instruction IT. */
-G_DEFINE_TYPE(GArmV7ITCondOperand, g_armv7_itcond_operand, G_TYPE_ARCH_OPERAND);
+G_DEFINE_TYPE(GArmV7ITCondOperand, g_armv7_itcond_operand, G_TYPE_ARMV7_OPERAND);
/******************************************************************************
@@ -120,8 +148,11 @@ static void g_armv7_itcond_operand_class_init(GArmV7ITCondOperandClass *klass)
operand = G_ARCH_OPERAND_CLASS(klass);
operand->compare = (operand_compare_fc)g_armv7_itcond_operand_compare;
+
operand->print = (operand_print_fc)g_armv7_itcond_operand_print;
+ operand->hash = (operand_hash_fc)g_armv7_itcond_operand_hash;
+
operand->load = (load_operand_fc)g_armv7_itcond_operand_load;
operand->store = (store_operand_fc)g_armv7_itcond_operand_store;
@@ -200,14 +231,17 @@ static void g_armv7_itcond_operand_finalize(GArmV7ITCondOperand *operand)
GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask)
{
GArmV7ITCondOperand *result; /* Structure à retourner */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
if (firstcond > ACC_NV)
return NULL;
result = g_object_new(G_TYPE_ARMV7_ITCOND_OPERAND, NULL);
- result->firstcond = firstcond;
- result->mask = mask;
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(result);
+
+ extra->firstcond = firstcond;
+ extra->mask = mask;
return G_ARCH_OPERAND(result);
@@ -229,8 +263,11 @@ GArchOperand *g_armv7_itcond_operand_new(uint8_t firstcond, uint8_t mask)
ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *operand)
{
ArmCondCode result; /* Condition à renvoyer */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
+
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
- result = operand->firstcond;
+ result = extra->firstcond;
return result;
@@ -252,8 +289,11 @@ ArmCondCode g_armv7_itcond_operand_get_firstcond(const GArmV7ITCondOperand *oper
uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand)
{
uint8_t result; /* Valeur à retourner */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
- result = operand->mask;
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ result = extra->mask;
return result;
@@ -283,12 +323,23 @@ uint8_t g_armv7_itcond_operand_get_mask(const GArmV7ITCondOperand *operand)
static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GArmV7ITCondOperand *b, bool lock)
{
int result; /* Bilan à faire remonter */
+ a7itcop_extra_data_t *ea; /* Données insérées à consulter*/
+ a7itcop_extra_data_t *eb; /* Données insérées à consulter*/
GArchOperandClass *class; /* Classe parente normalisée */
- result = sort_boolean(a->firstcond, b->firstcond);
+ ea = GET_ARMV7_ITCOND_OP_EXTRA(a);
+ eb = GET_ARMV7_ITCOND_OP_EXTRA(b);
+
+ if (lock)
+ {
+ LOCK_GOBJECT_EXTRA(ea);
+ LOCK_GOBJECT_EXTRA(eb);
+ }
+
+ result = sort_boolean(ea->firstcond, eb->firstcond);
if (result == 0)
- result = sort_unsigned_long(a->mask, b->mask);
+ result = sort_unsigned_long(ea->mask, eb->mask);
if (result == 0)
{
@@ -296,6 +347,12 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GA
result = class->compare(G_ARCH_OPERAND(a), G_ARCH_OPERAND(b), false);
}
+ if (lock)
+ {
+ UNLOCK_GOBJECT_EXTRA(eb);
+ UNLOCK_GOBJECT_EXTRA(ea);
+ }
+
return result;
}
@@ -316,9 +373,12 @@ static int g_armv7_itcond_operand_compare(const GArmV7ITCondOperand *a, const GA
static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBufferLine *line)
{
+ a7itcop_extra_data_t *extra; /* Données insérées à consulter*/
const char *kw; /* Mot clef à imprimer */
- switch (operand->firstcond)
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ switch (extra->firstcond)
{
case ACC_EQ: kw = "EQ"; break;
case ACC_NE: kw = "NE"; break;
@@ -352,6 +412,45 @@ static void g_armv7_itcond_operand_print(const GArmV7ITCondOperand *operand, GBu
/******************************************************************************
* *
+* Paramètres : operand = objet dont l'instance se veut unique. *
+* lock = précise le besoin en verrouillage. *
+* *
+* Description : Fournit l'empreinte d'un candidat à une centralisation. *
+* *
+* Retour : Empreinte de l'élément représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static guint g_armv7_itcond_operand_hash(const GArmV7ITCondOperand *operand, bool lock)
+{
+ guint result; /* Valeur à retourner */
+ a7itcop_extra_data_t *extra; /* Données internes à manipuler*/
+ GArchOperandClass *class; /* Classe parente normalisée */
+
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
+
+ if (lock)
+ LOCK_GOBJECT_EXTRA(extra);
+
+ class = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class);
+ result = class->hash(G_ARCH_OPERAND(operand), false);
+
+ result ^= extra->firstcond;
+
+ result ^= extra->mask;
+
+ if (lock)
+ UNLOCK_GOBJECT_EXTRA(extra);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = élément GLib à constuire. *
* storage = conservateur de données à manipuler ou NULL. *
* pbuf = zone tampon à lire. *
@@ -368,16 +467,26 @@ static bool g_armv7_itcond_operand_load(GArmV7ITCondOperand *operand, GObjectSto
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ uleb128_t value; /* Valeur ULEB128 à charger */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class);
result = parent->load(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extract_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true);
+ {
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
- if (result)
- result = extract_packed_buffer(pbuf, &operand->mask, sizeof(uint8_t), false);
+ result = unpack_uleb128(&value, pbuf);
+
+ if (result)
+ extra->firstcond = value;
+
+ if (result)
+ result = extract_packed_buffer(pbuf, &extra->mask, sizeof(uint8_t), false);
+
+ }
return result;
@@ -402,16 +511,22 @@ static bool g_armv7_itcond_operand_store(GArmV7ITCondOperand *operand, GObjectSt
{
bool result; /* Bilan à retourner */
GArchOperandClass *parent; /* Classe parente à consulter */
+ a7itcop_extra_data_t *extra; /* Données insérées à modifier */
parent = G_ARCH_OPERAND_CLASS(g_armv7_itcond_operand_parent_class);
result = parent->store(G_ARCH_OPERAND(operand), storage, pbuf);
if (result)
- result = extend_packed_buffer(pbuf, &operand->firstcond, sizeof(ArmCondCode), true);
+ {
+ extra = GET_ARMV7_ITCOND_OP_EXTRA(operand);
- if (result)
- result = extend_packed_buffer(pbuf, &operand->mask, sizeof(uint8_t), false);
+ result = pack_uleb128((uleb128_t []){ extra->firstcond }, pbuf);
+
+ if (result)
+ result = extend_packed_buffer(pbuf, &extra->mask, sizeof(uint8_t), false);
+
+ }
return result;