diff options
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r-- | src/arch/immediate.c | 155 |
1 files changed, 150 insertions, 5 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c index c1ad73c..876fa88 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -25,6 +25,7 @@ #include <malloc.h> +#include <stdarg.h> #include <stdio.h> @@ -56,10 +57,10 @@ struct _GImmOperand union { - uint8_t val8; /* Valeur sur 8 bits */ - uint16_t val16; /* Valeur sur 16 bits */ - uint32_t val32; /* Valeur sur 32 bits */ - uint64_t val64; /* Valeur sur 64 bits */ + int8_t val8; /* Valeur sur 8 bits */ + int16_t val16; /* Valeur sur 16 bits */ + int32_t val32; /* Valeur sur 32 bits */ + int64_t val64; /* Valeur sur 64 bits */ } signed_imm; @@ -148,7 +149,7 @@ static void g_imm_operand_init(GImmOperand *operand) GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data, off_t *pos, off_t len, SourceEndian endian) { - GImmOperand *result; /* Instruction à retourner */ + GImmOperand *result; /* Opérande à retourner */ result = g_object_new(G_TYPE_IMM_OPERAND, NULL); @@ -161,8 +162,30 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data goto gionfd_error; break; + case AOS_16_BITS_UNSIGNED: + if (!read_u16(&result->unsigned_imm.val16, data, pos, len, endian)) + goto gionfd_error; + break; + + case AOS_32_BITS_UNSIGNED: + if (!read_u32(&result->unsigned_imm.val32, data, pos, len, endian)) + goto gionfd_error; + break; + + case AOS_8_BITS_SIGNED: + if (!read_u8(&result->signed_imm.val8, data, pos, len, endian)) + goto gionfd_error; + break; + case AOS_16_BITS_SIGNED: + if (!read_u16(&result->signed_imm.val16, data, pos, len, endian)) + goto gionfd_error; + break; + case AOS_32_BITS_SIGNED: + if (!read_u32(&result->signed_imm.val32, data, pos, len, endian)) + goto gionfd_error; + break; } @@ -179,6 +202,128 @@ GArchOperand *g_imm_operand_new_from_data(MemoryDataSize size, const bin_t *data /****************************************************************************** * * +* Paramètres : 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. * +* * +* Retour : Instruction mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_imm_operand_new_from_value(AsmOperandSize size, ...) +{ + GImmOperand *result; /* Opérande à 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 */ + + if (size == AOS_UNDEFINED) return NULL; + + result = g_object_new(G_TYPE_IMM_OPERAND, NULL); + + result->size = size; + + va_start(ap, size); + + switch (size) + { + /* Pour GCC... */ + case AOS_UNDEFINED: + break; + case AOS_8_BITS_UNSIGNED: + uval8 = (uint8_t)va_arg(ap, unsigned int); + result->unsigned_imm.val8 = uval8; + break; + case AOS_16_BITS_UNSIGNED: + uval16 = (uint16_t)va_arg(ap, unsigned int); + result->unsigned_imm.val16 = uval16; + break; + case AOS_32_BITS_UNSIGNED: + uval32 = (uint32_t)va_arg(ap, unsigned int); + result->unsigned_imm.val32 = uval32; + break; + case AOS_64_BITS_UNSIGNED: + uval64 = (uint64_t)va_arg(ap, unsigned int); + result->unsigned_imm.val64 = uval64; + break; + case AOS_8_BITS_SIGNED: + sval8 = (int8_t)va_arg(ap, int); + result->signed_imm.val8 = sval8; + break; + case AOS_16_BITS_SIGNED: + sval16 = (int16_t)va_arg(ap, int); + result->signed_imm.val16 = sval16; + break; + case AOS_32_BITS_SIGNED: + sval32 = (int32_t)va_arg(ap, int); + result->signed_imm.val32 = sval32; + break; + case AOS_64_BITS_SIGNED: + sval64 = (int64_t)va_arg(ap, int); + result->signed_imm.val64 = sval64; + break; + } + + va_end(ap); + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = structure dont le contenu est à définir. * +* * +* Description : Indique le signe d'une valeur immédiate. * +* * +* Retour : true si la valeur est strictement négative, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_imm_operand_is_negative(const GImmOperand *operand) +{ + bool result; /* Bilan à renvoyer */ + + result = false; + + switch (operand->size) + { + case AOS_8_BITS_SIGNED: + result = (operand->signed_imm.val8 & 0x80); + break; + case AOS_16_BITS_SIGNED: + result = (operand->signed_imm.val16 & 0x8000); + break; + case AOS_32_BITS_SIGNED: + result = (operand->signed_imm.val32 & 0x80000000); + break; + case AOS_64_BITS_SIGNED: + result = (operand->signed_imm.val64 & 0x8000000000000000ll); + break; + default: + /* Traitement non nécessaire */ + break; + } + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande à traiter. * * format = format du binaire manipulé. * * syntax = type de représentation demandée. * |