diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-12-25 16:31:33 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-12-25 16:31:33 (GMT) |
commit | 19e1a97fafb1b73d0efcd995b31951daf1a5c661 (patch) | |
tree | 9cbc897ddb1d3005fb8dadfa3ad830c607acdddd /src/arch/immediate.c | |
parent | 9cab778bfaaca2589a383445e8569d99d73374d5 (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.c | 312 |
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; } |