summaryrefslogtreecommitdiff
path: root/src/arch/immediate.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-12-25 16:31:33 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-12-25 16:31:33 (GMT)
commit19e1a97fafb1b73d0efcd995b31951daf1a5c661 (patch)
tree9cbc897ddb1d3005fb8dadfa3ad830c607acdddd /src/arch/immediate.c
parent9cab778bfaaca2589a383445e8569d99d73374d5 (diff)
Cleaned all the code for immediate operands.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@444 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r--src/arch/immediate.c312
1 files changed, 122 insertions, 190 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index f8ef432..4d0c0b8 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -43,6 +43,7 @@ struct _GImmOperand
GArchOperand parent; /* Instance parente */
MemoryDataSize size; /* Taille de l'opérande */
+ uint64_t raw; /* Valeur transtypée */
/**
* Note : dans le cas d'une valeur signée,
@@ -197,7 +198,7 @@ static void g_imm_operand_finalize(GImmOperand *operand)
* *
* Paramètres : size = taille de l'opérande souhaitée. *
* data = flux de données à analyser. *
-* pos = position courante dans ce flux. [OUT] *
+* addr = position courante dans ce flux. [OUT] *
* end = limite des données à analyser. *
* low = position éventuelle des 4 bits visés. [OUT] *
* endian = ordre des bits dans la source. *
@@ -210,64 +211,87 @@ static void g_imm_operand_finalize(GImmOperand *operand)
* *
******************************************************************************/
-GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t end, bool *low, SourceEndian endian)
+GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
{
GImmOperand *result; /* Opérande à retourner */
+ off_t old; /* Ancienne tête de lecture */
+ off_t pos; /* Position physique */
+ uint8_t uval8; /* Valeur sur 8 bits */
+ uint16_t uval16; /* Valeur sur 16 bits */
+ uint32_t uval32; /* Valeur sur 32 bits */
+ uint64_t uval64; /* Valeur sur 64 bits */
+ int8_t sval8; /* Valeur sur 8 bits */
+ int16_t sval16; /* Valeur sur 16 bits */
+ int32_t sval32; /* Valeur sur 32 bits */
+ int64_t sval64; /* Valeur sur 64 bits */
result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
result->size = size;
+ pos = get_phy_addr(addr);
+ old = pos;
+
switch (size)
{
case MDS_4_BITS_UNSIGNED:
- if (!read_u4(&result->unsigned_imm.val8, data, pos, end, low, endian))
+ if (!read_u4(&uval8, data, &pos, end, low, endian))
goto gionfd_error;
+ result->raw = uval8;
break;
case MDS_8_BITS_UNSIGNED:
- if (!read_u8(&result->unsigned_imm.val8, data, pos, end, endian))
+ if (!read_u8(&uval8, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval8;
break;
case MDS_16_BITS_UNSIGNED:
- if (!read_u16(&result->unsigned_imm.val16, data, pos, end, endian))
+ if (!read_u16(&uval16, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval16;
break;
case MDS_32_BITS_UNSIGNED:
- if (!read_u32(&result->unsigned_imm.val32, data, pos, end, endian))
+ if (!read_u32(&uval32, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval32;
break;
case MDS_64_BITS_UNSIGNED:
- if (!read_u64(&result->unsigned_imm.val64, data, pos, end, endian))
+ if (!read_u64(&uval64, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = uval64;
break;
case MDS_4_BITS_SIGNED:
- if (!read_s4(&result->signed_imm.val8, data, pos, end, low, endian))
+ if (!read_s4(&sval8, data, &pos, end, low, endian))
goto gionfd_error;
+ result->raw = sval8;
break;
case MDS_8_BITS_SIGNED:
- if (!read_s8(&result->signed_imm.val8, data, pos, end, endian))
+ if (!read_s8(&sval8, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval8;
break;
case MDS_16_BITS_SIGNED:
- if (!read_s16(&result->signed_imm.val16, data, pos, end, endian))
+ if (!read_s16(&sval16, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval16;
break;
case MDS_32_BITS_SIGNED:
- if (!read_s32(&result->signed_imm.val32, data, pos, end, endian))
+ if (!read_s32(&sval32, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval32;
break;
case MDS_64_BITS_SIGNED:
- if (!read_s64(&result->signed_imm.val64, data, pos, end, endian))
+ if (!read_s64(&sval64, data, &pos, end, endian))
goto gionfd_error;
+ result->raw = sval64;
break;
case MDS_UNDEFINED:
@@ -276,6 +300,8 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
}
+ advance_vmpa(addr, pos - old);
+
return G_ARCH_OPERAND(result);
gionfd_error:
@@ -287,17 +313,10 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
}
-
-
-
/******************************************************************************
* *
-* Paramètres : size = taille de l'opérande souhaitée. *
-* data = flux de données à analyser. *
-* addr = position courante dans ce flux. [OUT] *
-* end = limite des données à analyser. *
-* low = position éventuelle des 4 bits visés. [OUT] *
-* endian = ordre des bits dans la source. *
+* Paramètres : size = taille de l'opérande souhaitée. *
+* value = valeur sur x bits à venir récupérer. *
* *
* Description : Crée un opérande réprésentant une valeur numérique. *
* *
@@ -307,121 +326,70 @@ GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *dat
* *
******************************************************************************/
-GArchOperand *_g_imm_operand_new_from_data2(MemoryDataSize size, const bin_t *data, vmpa2t *addr, off_t end, bool *low, SourceEndian endian)
+GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)
{
GImmOperand *result; /* Opérande à retourner */
- off_t old; /* Ancienne tête de lecture */
- off_t pos; /* Position physique */
- result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
-
- result->size = size;
-
- pos = get_phy_addr(addr);
- old = pos;
-
- switch (size)
- {
- case MDS_4_BITS_UNSIGNED:
- if (!read_u4(&result->unsigned_imm.val8, data, &pos, end, low, endian))
- goto gionfd_error;
- break;
-
- case MDS_8_BITS_UNSIGNED:
- if (!read_u8(&result->unsigned_imm.val8, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_16_BITS_UNSIGNED:
- if (!read_u16(&result->unsigned_imm.val16, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_32_BITS_UNSIGNED:
- if (!read_u32(&result->unsigned_imm.val32, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_64_BITS_UNSIGNED:
- if (!read_u64(&result->unsigned_imm.val64, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_4_BITS_SIGNED:
- if (!read_s4(&result->signed_imm.val8, data, &pos, end, low, endian))
- goto gionfd_error;
- break;
-
- case MDS_8_BITS_SIGNED:
- if (!read_s8(&result->signed_imm.val8, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_16_BITS_SIGNED:
- if (!read_s16(&result->signed_imm.val16, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_32_BITS_SIGNED:
- if (!read_s32(&result->signed_imm.val32, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_64_BITS_SIGNED:
- if (!read_s64(&result->signed_imm.val64, data, &pos, end, endian))
- goto gionfd_error;
- break;
-
- case MDS_UNDEFINED:
- goto gionfd_error;
- break;
+ if (size == MDS_UNDEFINED) return NULL;
- }
+ result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
- advance_vmpa(addr, pos - old);
+ g_imm_operand_set_value(result, size, value);
return G_ARCH_OPERAND(result);
- gionfd_error:
+}
- g_object_unref(G_OBJECT(result));
- return NULL;
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* *
+* Description : Renseigne la taille de la valeur indiquée à la construction. *
+* *
+* Retour : Taille de la valeur représentée en mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+{
+ return operand->size;
}
/******************************************************************************
* *
-* Paramètres : size = taille de l'opérande souhaitée. *
+* Paramètres : operand = structure dont le contenu est à consulter. *
+* size = taille de l'opérande souhaitée. *
* ... = valeur sur x bits à venir récupérer. *
* *
-* Description : Crée un opérande réprésentant une valeur numérique. *
+* Description : Fournit la valeur portée par une opérande numérique. *
* *
-* Retour : Instruction mise en place. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
+bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...)
{
- GImmOperand *result; /* Opérande à retourner */
+ bool result; /* Bilan à retourner */
va_list ap; /* Liste des compléments */
- uint8_t uval8; /* Valeur sur 8 bits */
- uint16_t uval16; /* Valeur sur 16 bits */
- uint32_t uval32; /* Valeur sur 32 bits */
- uint64_t uval64; /* Valeur sur 64 bits */
- int8_t sval8; /* Valeur sur 8 bits */
- int16_t sval16; /* Valeur sur 16 bits */
- int32_t sval32; /* Valeur sur 32 bits */
- int64_t sval64; /* Valeur sur 64 bits */
+ uint8_t *uval8; /* Valeur sur 8 bits */
+ uint16_t *uval16; /* Valeur sur 16 bits */
+ uint32_t *uval32; /* Valeur sur 32 bits */
+ uint64_t *uval64; /* Valeur sur 64 bits */
+ int8_t *sval8; /* Valeur sur 8 bits */
+ int16_t *sval16; /* Valeur sur 16 bits */
+ int32_t *sval32; /* Valeur sur 32 bits */
+ int64_t *sval64; /* Valeur sur 64 bits */
- if (size == MDS_UNDEFINED) return NULL;
+ if (operand->size != size) return false;
- result = g_object_new(G_TYPE_IMM_OPERAND, NULL);
-
- result->size = size;
+ result = true;
va_start(ap, size);
@@ -429,65 +397,73 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, ...)
{
/* Pour GCC... */
case MDS_UNDEFINED:
+ result = false;
break;
case MDS_4_BITS_UNSIGNED:
case MDS_8_BITS_UNSIGNED:
- uval8 = (uint8_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val8 = uval8;
+ uval8 = va_arg(ap, uint8_t *);
+ *uval8 = operand->raw;
break;
case MDS_16_BITS_UNSIGNED:
- uval16 = (uint16_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val16 = uval16;
+ uval16 = va_arg(ap, uint16_t *);
+ *uval16 = operand->raw;
break;
case MDS_32_BITS_UNSIGNED:
- uval32 = (uint32_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val32 = uval32;
+ uval32 = va_arg(ap, uint32_t *);
+ *uval32 = operand->raw;
break;
case MDS_64_BITS_UNSIGNED:
- uval64 = (uint64_t)va_arg(ap, unsigned int);
- result->unsigned_imm.val64 = uval64;
+ uval64 = va_arg(ap, uint64_t *);
+ *uval64 = operand->raw;
break;
case MDS_4_BITS_SIGNED:
case MDS_8_BITS_SIGNED:
- sval8 = (int8_t)va_arg(ap, int);
- result->signed_imm.val8 = sval8;
+ sval8 = va_arg(ap, int8_t *);
+ *sval8 = operand->raw;
break;
case MDS_16_BITS_SIGNED:
- sval16 = (int16_t)va_arg(ap, int);
- result->signed_imm.val16 = sval16;
+ sval16 = va_arg(ap, int16_t *);
+ *sval16 = operand->raw;
break;
case MDS_32_BITS_SIGNED:
- sval32 = (int32_t)va_arg(ap, int);
- result->signed_imm.val32 = sval32;
+ sval32 = va_arg(ap, int32_t *);
+ *sval32 = operand->raw;
break;
case MDS_64_BITS_SIGNED:
- sval64 = (int64_t)va_arg(ap, int);
- result->signed_imm.val64 = sval64;
+ sval64 = va_arg(ap, int64_t *);
+ *sval64 = operand->raw;
break;
}
va_end(ap);
- return G_ARCH_OPERAND(result);
+ return result;
}
/******************************************************************************
* *
-* Paramètres : operand = structure dont le contenu est à consulter. *
+* Paramètres : operand = structure dont le contenu est à mettre à jour. *
+* size = taille de l'opérande souhaitée. *
+* value = valeur sur x bits à venir récupérer. *
* *
-* Description : Renseigne la taille de la valeur indiquée à la construction. *
+* Description : Définit la nouvelle valeur de l'opérande à une valeur. *
* *
-* Retour : Taille de la valeur représentée en mémoire. *
+* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
-MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand)
+bool g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value)
{
- return operand->size;
+ if (size == MDS_UNDEFINED) return false;
+
+ operand->size = size;
+ operand->raw = value;
+
+ return true;
}
@@ -589,19 +565,15 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
switch (operand->size)
{
case MDS_4_BITS_SIGNED:
- result = (operand->signed_imm.val8 & 0x08);
- break;
case MDS_8_BITS_SIGNED:
- result = (operand->signed_imm.val8 & 0x80);
- break;
case MDS_16_BITS_SIGNED:
- result = (operand->signed_imm.val16 & 0x8000);
- break;
case MDS_32_BITS_SIGNED:
- result = (operand->signed_imm.val32 & 0x80000000);
- break;
case MDS_64_BITS_SIGNED:
- result = (operand->signed_imm.val64 & 0x8000000000000000ll);
+ /**
+ * Pour les valeurs plus petites que 64 bits, le compilateur
+ * réalise une extension de signe lors du transtypage.
+ */
+ result = (operand->raw & 0x8000000000000000ll);
break;
default:
result = false;
@@ -627,46 +599,7 @@ bool g_imm_operand_is_negative(const GImmOperand *operand)
bool g_imm_operand_is_null(const GImmOperand *operand)
{
- bool result; /* Bilan à renvoyer */
-
- switch (operand->size)
- {
- case MDS_4_BITS_SIGNED:
- result = !(operand->signed_imm.val8 & 0x0f);
- break;
- case MDS_4_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val8 & 0x0f);
- break;
- case MDS_8_BITS_SIGNED:
- result = !(operand->signed_imm.val8 & 0xff);
- break;
- case MDS_8_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val8 & 0xff);
- break;
- case MDS_16_BITS_SIGNED:
- result = !(operand->signed_imm.val16 & 0xffff);
- break;
- case MDS_16_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val16 & 0xffff);
- break;
- case MDS_32_BITS_SIGNED:
- result = !(operand->signed_imm.val32 & 0xffffffff);
- break;
- case MDS_32_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val32 & 0xffffffff);
- break;
- case MDS_64_BITS_SIGNED:
- result = !(operand->signed_imm.val64 & 0xffffffffffffffffll);
- break;
- case MDS_64_BITS_UNSIGNED:
- result = !(operand->unsigned_imm.val64 & 0xffffffffffffffffll);
- break;
- default:
- result = false;
- break;
- }
-
- return result;
+ return (operand->raw == 0ll);
}
@@ -750,43 +683,43 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt
break;
case MDS_4_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint8_t)operand->raw);
break;
case MDS_8_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint8_t)operand->raw);
break;
case MDS_16_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint16_t)operand->raw);
break;
case MDS_32_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint32_t)operand->raw);
break;
case MDS_64_BITS_UNSIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->unsigned_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (uint64_t)operand->raw);
break;
case MDS_4_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int8_t)operand->raw);
break;
case MDS_8_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val8);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int8_t)operand->raw);
break;
case MDS_16_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val16);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int16_t)operand->raw);
break;
case MDS_32_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val32);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int32_t)operand->raw);
break;
case MDS_64_BITS_SIGNED:
- result = snprintf(value, VMPA_MAX_SIZE, format, operand->signed_imm.val64);
+ result = snprintf(value, VMPA_MAX_SIZE, format, (int64_t)operand->raw);
break;
}
@@ -857,7 +790,6 @@ bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr)
*addr = operand->unsigned_imm.val64;
break;
default:
- *addr = operand->signed_imm.val32;//////
result = false;
break;
}