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.c91
1 files changed, 56 insertions, 35 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 339364f..a86509c 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -145,7 +145,7 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)
static void g_arch_instruction_init(GArchInstruction *instr)
{
- instr->operands_lock = 0;
+ instr->operands = NULL;
instr->from_count = 0;
instr->to_count = 0;
@@ -472,7 +472,7 @@ void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchReg
void g_arch_instruction_lock_operands(GArchInstruction *instr)
{
- g_bit_lock(&instr->operands_lock, 0);
+ lock_flat_array(&instr->operands);
}
@@ -491,7 +491,7 @@ void g_arch_instruction_lock_operands(GArchInstruction *instr)
void g_arch_instruction_unlock_operands(GArchInstruction *instr)
{
- g_bit_unlock(&instr->operands_lock, 0);
+ unlock_flat_array(&instr->operands);
}
@@ -513,10 +513,7 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera
{
g_arch_instruction_lock_operands(instr);
- instr->operands_count++;
- instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *));
-
- instr->operands[instr->operands_count - 1] = operand;
+ add_item_to_flat_array(&instr->operands, &operand, sizeof(GArchOperand *));
g_arch_instruction_unlock_operands(instr);
@@ -537,9 +534,11 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera
size_t _g_arch_instruction_count_operands(const GArchInstruction *instr)
{
- assert(instr->operands_lock != 0);
+ size_t result; /* Décompte à retourner */
+
+ result = count_flat_array_items(instr->operands);
- return instr->operands_count;
+ return result;
}
@@ -560,11 +559,11 @@ size_t _g_arch_instruction_count_operands(const GArchInstruction *instr)
GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index)
{
GArchOperand *result; /* Opérande à retourner */
+ GArchOperand **ptr; /* Adresse dans le tableau */
- assert(instr->operands_lock != 0);
+ ptr = get_flat_array_item(instr->operands, index, sizeof(GArchOperand *));
- if (index >= instr->operands_count) result = NULL;
- else result = instr->operands[index];
+ result = *ptr;
/* TODO : incrémenter la référence ! */
@@ -587,29 +586,34 @@ GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, siz
* *
******************************************************************************/
-void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old)
+void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, GArchOperand *old)
{
+ size_t count; /* Nombre d'opérandes en place */
size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
- assert(instr->operands_lock != 0);
+ count = _g_arch_instruction_count_operands(instr);
+
+ for (i = 0; i < count; i++)
+ {
+ op = _g_arch_instruction_get_operand(instr, i);
- for (i = 0; i < instr->operands_count; i++)
- if (instr->operands[i] == old)
+ if (op == old)
break;
- if (i < instr->operands_count)
- {
- g_object_unref(G_OBJECT(instr->operands[i]));
- instr->operands[i] = new;
}
+ rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *));
+
+ g_object_unref(G_OBJECT(old));
+
}
/******************************************************************************
* *
-* Paramètres : instr = instance à mettre à jour. *
-* opererand = instruction à venir dissocier. *
+* Paramètres : instr = instance à mettre à jour. *
+* target = instruction à venir dissocier. *
* *
* Description : Détache un opérande liée d'une instruction. *
* *
@@ -619,22 +623,26 @@ void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
* *
******************************************************************************/
-void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand)
+void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *target)
{
+ size_t count; /* Nombre d'opérandes en place */
size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
+
+ count = _g_arch_instruction_count_operands(instr);
- assert(instr->operands_lock != 0);
+ for (i = 0; i < count; i++)
+ {
+ op = _g_arch_instruction_get_operand(instr, i);
- for (i = 0; i < instr->operands_count; i++)
- if (instr->operands[i] == operand)
+ if (op == target)
break;
- if ((i + 1) < instr->operands_count)
- memmove(&instr->operands[i], &instr->operands[i + 1],
- (instr->operands_count - i - 1) * sizeof(GArchOperand *));
+ }
+
+ rem_item_from_flat_array(&instr->operands, i, sizeof(GArchOperand *));
- instr->operands_count--;
- instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *));
+ g_object_unref(G_OBJECT(target));
}
@@ -1178,7 +1186,9 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line
{
const char *key; /* Mot clef principal */
size_t klen; /* Taille de ce mot clef */
+ size_t count; /* Nombre d'opérandes en place */
size_t i; /* Boucle de parcours */
+ GArchOperand *op; /* Opérande à manipuler */
g_buffer_line_fill_vmpa(line, get_mrange_addr(&instr->range), MDS_32_BITS_UNSIGNED, MDS_32_BITS_UNSIGNED);
@@ -1191,21 +1201,32 @@ static void _g_arch_instruction_print(GArchInstruction *instr, GBufferLine *line
g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION, NULL);
- if (instr->operands_count > 0)
+ /* Liste des opérandes */
+
+ g_arch_instruction_lock_operands(instr);
+
+ count = _g_arch_instruction_count_operands(instr);
+
+ if (count > 0)
{
- g_arch_operand_print(instr->operands[0], line, 0/*syntax*/);
+ op = _g_arch_instruction_get_operand(instr, 0);
+ g_arch_operand_print(op, line, 0/*syntax*/);
- for (i = 1; i < instr->operands_count; i++)
+ for (i = 1; i < count; i++)
{
g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
- g_arch_operand_print(instr->operands[i], line, 0/*syntax*/);
+ op = _g_arch_instruction_get_operand(instr, i);
+
+ g_arch_operand_print(op, line, 0/*syntax*/);
}
}
+ g_arch_instruction_unlock_operands(instr);
+
}