diff options
Diffstat (limited to 'src/arch/arm/v7/helpers.c')
-rw-r--r-- | src/arch/arm/v7/helpers.c | 190 |
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; + +} |