summaryrefslogtreecommitdiff
path: root/src/arch/arm/v7/helpers.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2014-11-24 06:49:23 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2014-11-24 06:49:23 (GMT)
commit96eee784837e6ed4cf9ce5f1cb2e0f8bff8bd9bf (patch)
treec7fd1108066e6359766bc18f8883b67b2b7f082f /src/arch/arm/v7/helpers.c
parent2d833afa673b63a1a61e22ea2cdde59ed60b5ad1 (diff)
Update the list of handled ARM instructions
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@423 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/arm/v7/helpers.c')
-rw-r--r--src/arch/arm/v7/helpers.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/arch/arm/v7/helpers.c b/src/arch/arm/v7/helpers.c
index e7c9ad8..8acfeb5 100644
--- a/src/arch/arm/v7/helpers.c
+++ b/src/arch/arm/v7/helpers.c
@@ -28,6 +28,83 @@
#include "../../register.h"
#include "../../immediate.h"
#include "../../../common/asm.h"
+#include "../../../common/bconst.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : x = valeur sur 32 bits maximum à traiter. *
+* shift = nombre de décallages visés. *
+* *
+* Description : Effectue une rotation vers la droit d'une valeur. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : Correspond à la pseudo fonction 'ROR_C'. *
+* *
+******************************************************************************/
+
+GArchOperand *ror_armv7_imm(uint32_t x, unsigned int shift)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ uint32_t val32; /* Valeur sur 32 bits */
+
+ shift %= 32;
+
+ val32 = (x >> shift) | (x << (32 - shift));
+
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+// Shift_C()
+// =========
+(bits(N), bit) Shift_C(bits(N) value, SRType type, integer amount, bit carry_in)
+assert !(type == SRType_RRX && amount != 1);
+if amount == 0 then
+(result, carry_out) = (value, carry_in);
+else
+case type of
+
+when SRType_LSL
+(result, carry_out) = LSL_C(value, amount);
+
+when SRType_LSR
+(result, carry_out)
+
+when SRType_ASR
+(result, carry_out)
+
+when SRType_ROR
+(result, carry_out)
+
+when SRType_RRX
+(result, carry_out)
+= LSR_C(value, amount);
+= ASR_C(value, amount);
+= ROR_C(value, amount);
+= RRX_C(value, carry_in);
+
+#endif
+
+
+
@@ -87,6 +164,73 @@ GArchOperand *sign_extend_armv7_imm(uint32_t value, bool topbit, unsigned int si
/******************************************************************************
* *
+* Paramètres : value = valeur sur 32 bits maximum à traiter. *
+* *
+* Description : Etend une valeur immédiate en mode 'Thumb' ARMv7. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *thumb_expand_armv7_imm(uint32_t value)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ uint8_t byte; /* Octet à reproduire */
+ uint32_t val32; /* Valeur sur 32 bits */
+ uint32_t unrotated; /* Transformation à décaller */
+
+ result = NULL;
+
+ if (((value >> 10) & b11) == b00)
+ {
+ byte = value & 0xff;
+
+ switch ((value >> 8) & b11)
+ {
+ case b00:
+ result = zero_extend_armv7_imm(byte, 32);
+ break;
+
+ case b01:
+ if (byte == 0) return NULL;
+ val32 = byte << 16 | byte;
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+ break;
+
+ case b10:
+ if (byte == 0) return NULL;
+ val32 = byte << 24 | byte << 8;
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+ break;
+
+ case b11:
+ if (byte == 0) return NULL;
+ val32 = byte << 24 | byte << 16 | byte << 8 | byte;
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+ break;
+
+ }
+
+ }
+ else
+ {
+ unrotated = 1 << 7 | (value & 0x3f);
+ result = ror_armv7_imm(unrotated, (value >> 7) & 0x1f);
+ }
+
+ return result;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+* *
* Paramètres : index = indice du registre correspondant. *
* *
* Description : Crée un opérande représentant un registre ARMv7. *
@@ -112,3 +256,49 @@ GArchOperand *translate_armv7_register(uint8_t index)
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur sur 32 bits maximum à traiter. *
+* size = taille de la valeur finale à constituer. *
+* *
+* Description : Réalise un simple transtypage de valeur entière. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : Correspond à la pseudo fonction 'ZeroExtend'. *
+* *
+******************************************************************************/
+
+GArchOperand *zero_extend_armv7_imm(uint32_t value, unsigned int size)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ MemoryDataSize mds; /* Conversion de la taille */
+ uint32_t val4; /* Valeur sur 4 bits */
+ uint32_t val8; /* Valeur sur 8 bits */
+ uint32_t val16; /* Valeur sur 16 bits */
+ uint32_t val32; /* Valeur sur 32 bits */
+
+ result = NULL;
+
+ switch (size)
+ {
+
+#define ZERO_EXTEND_CASE(sz) \
+ case sz: \
+ mds = MDS_ ## sz ## _BITS_UNSIGNED; \
+ val ## sz = value; \
+ result = g_imm_operand_new_from_value(mds, val ## sz); \
+ break;
+
+ ZERO_EXTEND_CASE(4);
+ ZERO_EXTEND_CASE(8);
+ ZERO_EXTEND_CASE(16);
+ ZERO_EXTEND_CASE(32);
+
+ }
+
+ return result;
+
+}