summaryrefslogtreecommitdiff
path: root/src/arch/instruction.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/instruction.c')
-rw-r--r--src/arch/instruction.c85
1 files changed, 75 insertions, 10 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 14e78dc..a2ba138 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -30,6 +30,7 @@
#include "instruction-int.h"
+#include "sharing/container-int.h"
#include "../glibext/linegen-int.h"
@@ -40,8 +41,11 @@ static void g_arch_instruction_class_init(GArchInstructionClass *);
/* Initialise une instance d'opérande d'architecture. */
static void g_arch_instruction_init(GArchInstruction *);
+/* Procède à l'initialisation de l'interface de partage. */
+static void g_arch_instruction_share_interface_init(GShareContainerInterface *);
+
/* Procède à l'initialisation de l'interface de génération. */
-static void g_arch_instruction_interface_init(GLineGeneratorInterface *);
+static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *);
/* Supprime toutes les références externes. */
static void g_arch_instruction_dispose(GArchInstruction *);
@@ -76,7 +80,8 @@ static void g_arch_instruction_print(GArchInstruction *, GBufferLine *, size_t,
/* Indique le type défini pour une instruction d'architecture. */
G_DEFINE_TYPE_WITH_CODE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_interface_init));
+ G_IMPLEMENT_INTERFACE(G_TYPE_SHARE_CONTAINER, g_arch_instruction_share_interface_init)
+ G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_arch_instruction_generator_interface_init));
/******************************************************************************
@@ -134,6 +139,25 @@ static void g_arch_instruction_init(GArchInstruction *instr)
* *
* Paramètres : iface = interface GLib à initialiser. *
* *
+* Description : Procède à l'initialisation de l'interface de partage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_arch_instruction_share_interface_init(GShareContainerInterface *iface)
+{
+ iface->replace = (replace_shared_fc)g_arch_instruction_replace_operand;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : iface = interface GLib à initialiser. *
+* *
* Description : Procède à l'initialisation de l'interface de génération. *
* *
* Retour : - *
@@ -142,7 +166,7 @@ static void g_arch_instruction_init(GArchInstruction *instr)
* *
******************************************************************************/
-static void g_arch_instruction_interface_init(GLineGeneratorInterface *iface)
+static void g_arch_instruction_generator_interface_init(GLineGeneratorInterface *iface)
{
iface->count = (linegen_count_lines_fc)g_arch_instruction_count_lines;
iface->compute = (linegen_compute_fc)g_arch_instruction_compute_addr;
@@ -475,8 +499,8 @@ void g_arch_instruction_unlock_operands(GArchInstruction *instr)
/******************************************************************************
* *
-* Paramètres : instr = instance à mettre à jour. *
-* opererand = instruction à venir associer. *
+* Paramètres : instr = instance à mettre à jour. *
+* operand = instruction à venir associer. *
* *
* Description : Attache un opérande supplémentaire à une instruction. *
* *
@@ -552,23 +576,55 @@ GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, siz
/******************************************************************************
* *
* Paramètres : instr = instance à mettre à jour. *
-* new = nouvelle opérande à attacher. *
+* old = ancien opérande à remplacer. *
+* new = nouvel opérande à intégrer. *
+* *
+* Description : Remplace un opérande d'une instruction par un autre. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new)
+{
+ bool result; /* Bilan à retourner */
+
+ g_arch_instruction_lock_operands(instr);
+
+ result = _g_arch_instruction_replace_operand(instr, old, new);
+
+ g_arch_instruction_unlock_operands(instr);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance à mettre à jour. *
* old = ancienne opérande à détacher. *
+* new = nouvelle opérande à attacher. *
* *
* Description : Remplace un opérande d'une instruction par un autre. *
* *
-* Retour : - *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, GArchOperand *old)
+bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *old, GArchOperand *new)
{
+ bool result; /* Bilan à retourner */
size_t count; /* Nombre d'opérandes en place */
size_t i; /* Boucle de parcours */
GArchOperand *op; /* Opérande à manipuler */
+ result = false;
+
count = _g_arch_instruction_count_operands(instr);
for (i = 0; i < count; i++)
@@ -576,13 +632,22 @@ void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
op = _g_arch_instruction_get_operand(instr, i);
if (op == old)
+ {
+ result = true;
break;
+ }
}
- rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *));
+ if (result)
+ {
+ rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *));
+
+ g_object_unref(G_OBJECT(old));
- g_object_unref(G_OBJECT(old));
+ }
+
+ return result;
}