diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-12-03 22:41:29 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-12-03 22:41:29 (GMT) |
commit | 172fce9bab61de1ffa89f731b5d10f96e209afc1 (patch) | |
tree | 31aee5a141979fa99bbf88cbf2b7990de0ec3832 /src/arch/arm/v7/pseudo.c | |
parent | f7ef27195f8c9dc35e5e210a333b74fcfae5ad71 (diff) |
Begun to support more than the only 'ARMv7' architecture for ARM (ARM / Thumb16 / Thumb32).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@433 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/arm/v7/pseudo.c')
-rw-r--r-- | src/arch/arm/v7/pseudo.c | 253 |
1 files changed, 178 insertions, 75 deletions
diff --git a/src/arch/arm/v7/pseudo.c b/src/arch/arm/v7/pseudo.c index aac8bb7..53064bb 100644 --- a/src/arch/arm/v7/pseudo.c +++ b/src/arch/arm/v7/pseudo.c @@ -38,24 +38,27 @@ * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * * carry = retenue enventuelle à constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'LSL_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_lsl_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +bool armv7_lsl_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry, uint32_t *value) { - assert(n <= 32); - assert(shift > 0); + if (n > 32) return false; + if (shift == 0) return false; if (carry != NULL) *carry = x & (1 << (n - 1)); - return x << shift; + *value = x << shift; + + return true; } @@ -65,24 +68,25 @@ uint32_t armv7_lsl_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry * Paramètres : x = valeur sur 32 bits maximum à traiter. * * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'LSL'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_lsl(uint32_t x, unsigned int n, unsigned int shift) +bool armv7_lsl(uint32_t x, unsigned int n, unsigned int shift, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + bool result; /* Bilan final à retourner */ if (shift == 0) - result = x; + result = true; else - result = armv7_lsl_c(x, n, shift, NULL); + result = armv7_lsl_c(x, n, shift, NULL, value); return result; @@ -95,24 +99,27 @@ uint32_t armv7_lsl(uint32_t x, unsigned int n, unsigned int shift) * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * * carry = retenue enventuelle à constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'LSR_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_lsr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +bool armv7_lsr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry, uint32_t *value) { - assert(n <= 32); - assert(shift > 0); + if (n > 32) return false; + if (shift == 0) return false; if (carry != NULL) *carry = x & (1 << (shift - 1)); - return x >> shift; + *value = x >> shift; + + return true; } @@ -122,24 +129,25 @@ uint32_t armv7_lsr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry * Paramètres : x = valeur sur 32 bits maximum à traiter. * * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'LSR'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_lsr(uint32_t x, unsigned int n, unsigned int shift) +bool armv7_lsr(uint32_t x, unsigned int n, unsigned int shift, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + bool result; /* Bilan final à retourner */ if (shift == 0) result = x; else - result = armv7_lsr_c(x, n, shift, NULL); + result = armv7_lsr_c(x, n, shift, NULL, value); return result; @@ -152,24 +160,27 @@ uint32_t armv7_lsr(uint32_t x, unsigned int n, unsigned int shift) * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * * carry = retenue enventuelle à constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'ASR_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_asr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +bool armv7_asr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry, uint32_t *value) { - assert(n <= 32); - assert(shift > 0); + if (n > 32) return false; + if (shift == 0) return false; if (carry != NULL) *carry = x & (1 << (shift - 1)); - return ((int32_t)x) >> shift; + *value = ((int32_t)x) >> shift; + + return true; } @@ -179,24 +190,25 @@ uint32_t armv7_asr_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry * Paramètres : x = valeur sur 32 bits maximum à traiter. * * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'ASR'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_asr(uint32_t x, unsigned int n, unsigned int shift) +bool armv7_asr(uint32_t x, unsigned int n, unsigned int shift, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + bool result; /* Bilan final à retourner */ if (shift == 0) - result = x; + result = true; else - result = armv7_asr_c(x, n, shift, NULL); + result = armv7_asr_c(x, n, shift, NULL, value); return result; @@ -209,28 +221,27 @@ uint32_t armv7_asr(uint32_t x, unsigned int n, unsigned int shift) * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * * carry = retenue enventuelle à constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'ROR_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_ror_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry) +bool armv7_ror_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + if (n > 32) return false; + if (shift == 0) return false; - assert(n <= 32); - assert(shift > 0); - - result = (x >> shift) | (x << (32 - shift)); + *value = (x >> shift) | (x << (32 - shift)); if (carry != NULL) - *carry = result & (1 << (n - 1)); + *carry = *value & (1 << (n - 1)); - return result; + return true; } @@ -240,24 +251,25 @@ uint32_t armv7_ror_c(uint32_t x, unsigned int n, unsigned int shift, bool *carry * Paramètres : x = valeur sur 32 bits maximum à traiter. * * n = nombre de bits à prendre en compte. * * shift = nombre de décallages visés. * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'ROR'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_ror(uint32_t x, unsigned int n, unsigned int shift) +bool armv7_ror(uint32_t x, unsigned int n, unsigned int shift, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + bool result; /* Bilan final à retourner */ if (shift == 0) - result = x; + result = true; else - result = armv7_ror_c(x, n, shift, NULL); + result = armv7_ror_c(x, n, shift, NULL, value); return result; @@ -269,29 +281,27 @@ uint32_t armv7_ror(uint32_t x, unsigned int n, unsigned int shift) * Paramètres : x = valeur sur 32 bits maximum à traiter. * * n = nombre de bits à prendre en compte. * * carry = retenue enventuelle à utiliser puis constituer. [OUT]* +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'RRX_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_rrx_c(uint32_t x, unsigned int n, bool *carry) +bool armv7_rrx_c(uint32_t x, unsigned int n, bool *carry, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ bool new_c; /* Nouvelle retenue à retenir */ - assert(carry != NULL); - new_c = x & 0x1; - result = (*carry ? 1 : 0) << (n - 1) | x >> 1; + *value = (*carry ? 1 : 0) << (n - 1) | x >> 1; *carry = new_c; - return result; + return true; } @@ -301,18 +311,19 @@ uint32_t armv7_rrx_c(uint32_t x, unsigned int n, bool *carry) * Paramètres : x = valeur sur 32 bits maximum à traiter. * * n = nombre de bits à prendre en compte. * * carry = retenue enventuelle à utiliser. * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'RRX'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_rrx(uint32_t x, unsigned int n, bool carry) +bool armv7_rrx(uint32_t x, unsigned int n, bool carry, uint32_t *value) { - return armv7_rrx_c(x, n, &carry); + return armv7_rrx_c(x, n, &carry, value); } @@ -321,18 +332,19 @@ uint32_t armv7_rrx(uint32_t x, unsigned int n, bool carry) * * * Paramètres : imm12 = valeur sur 32 bits maximum à traiter. * * carry = retenue enventuelle à utiliser / constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'ARMExpandImm_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_arm_expand_imm_c(uint32_t imm12, bool *carry) +bool armv7_arm_expand_imm_c(uint32_t imm12, bool *carry, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + bool result; /* Bilan final à retourner */ uint32_t unrotated; /* Transformation à décaller */ /** @@ -341,7 +353,7 @@ uint32_t armv7_arm_expand_imm_c(uint32_t imm12, bool *carry) unrotated = armv7_zero_extend(imm12 & 0xff, 8, 32); - result = armv7_shift(unrotated, 32, SRType_ROR, 2 * ((imm12 >> 8) & 0xf), carry); + result = armv7_shift(unrotated, 32, SRType_ROR, 2 * ((imm12 >> 8) & 0xf), carry, value); return result; @@ -352,18 +364,107 @@ uint32_t armv7_arm_expand_imm_c(uint32_t imm12, bool *carry) * * * Paramètres : imm12 = valeur sur 32 bits maximum à traiter. * * carry = retenue enventuelle à utiliser / constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'ARMExpandImm'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool armv7_arm_expand_imm(uint32_t imm12, uint32_t *value) +{ + return armv7_arm_expand_imm_c(imm12, (bool []) { false /* FIXME : APSR.C */ }, value); + +} + + +/****************************************************************************** +* * +* Paramètres : imm12 = valeur sur 32 bits maximum à traiter. * +* carry = retenue enventuelle à utiliser / constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * +* * +* Description : Traduit la fonction 'ThumbExpandImm_C'. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool armv7_thumb_expand_imm_c(uint32_t imm12, bool *carry, uint32_t *value) +{ + bool result; /* Conclusion à faire remonter */ + uint8_t byte; /* Octet à reproduire */ + uint32_t unrotated; /* Transformation à décaller */ + + result = true; + + if (((imm12 >> 10) & b11) == b00) + { + byte = imm12 & 0xff; + + switch ((imm12 >> 8) & b11) + { + case b00: + *value = armv7_zero_extend(byte, 8, 32); + break; + + case b01: + if (byte == 0) + result = false; + else + *value = byte << 16 | byte; + break; + + case b10: + if (byte == 0) + result = false; + else + *value = byte << 24 | byte << 8; + break; + + case b11: + if (byte == 0) + result = false; + else + *value = byte << 24 | byte << 16 | byte << 8 | byte; + break; + + } + + } + else + { + unrotated = 1 << 7 | (imm12 & 0x3f); + result = armv7_ror_c(unrotated, 32, (imm12 >> 7) & 0x1f, carry, value); + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : imm12 = valeur sur 32 bits maximum à traiter. * +* carry = retenue enventuelle à utiliser / constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * +* * +* Description : Traduit la fonction 'ThumbExpandImm'. * +* * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_arm_expand_imm(uint32_t imm12) +bool armv7_thumb_expand_imm(uint32_t imm12, uint32_t *value) { - return armv7_arm_expand_imm_c(imm12, (bool []) { false /* FIXME : APSR.C */ }); + return armv7_thumb_expand_imm_c(imm12, (bool []) { false /* FIXME : APSR.C */ }, value); } @@ -464,7 +565,7 @@ bool armv7_decode_reg_shift(uint8_t type2, SRType *type) break; case b11: - *type = SRType_ROR; + *type = SRType_ROR; break; default: @@ -485,45 +586,46 @@ bool armv7_decode_reg_shift(uint8_t type2, SRType *type) * type = type d'opération à mener. * * amount = quantité liée à l'opération à mener. * * carry = retenue enventuelle à utiliser / constituer. [OUT] * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'Shift_C'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_shift_c(uint32_t x, unsigned int n, SRType type, unsigned int amount, bool *carry) +bool armv7_shift_c(uint32_t x, unsigned int n, SRType type, unsigned int amount, bool *carry, uint32_t *value) { - uint32_t result; /* Valeur finale à retourner */ + bool result; /* Bilan final à retourner */ - assert(!(type == SRType_RRX && amount != 1)); + if (type == SRType_RRX && amount != 1) return false; - if (amount == 0) return x; + if (amount == 0) return true; - result = 0; /* Pour GCC... */ + result = true; /* Pour GCC... */ switch (type) { case SRType_LSL: - result = armv7_lsl_c(x, n, amount, carry); + result = armv7_lsl_c(x, n, amount, carry, value); break; case SRType_LSR: - result = armv7_lsr_c(x, n, amount, carry); + result = armv7_lsr_c(x, n, amount, carry, value); break; case SRType_ASR: - result = armv7_asr_c(x, n, amount, carry); + result = armv7_asr_c(x, n, amount, carry, value); break; case SRType_ROR: - result = armv7_ror_c(x, n, amount, carry); + result = armv7_ror_c(x, n, amount, carry, value); break; case SRType_RRX: - result = armv7_rrx_c(x, n, carry); + result = armv7_rrx_c(x, n, carry, value); break; } @@ -540,18 +642,19 @@ uint32_t armv7_shift_c(uint32_t x, unsigned int n, SRType type, unsigned int amo * type = type d'opération à mener. * * amount = quantité liée à l'opération à mener. * * carry = retenue enventuelle à utiliser. * +* value = nouvelle valeur calculée. [OUT] * * * * Description : Traduit la fonction 'Shift'. * * * -* Retour : Nouvelle valeur calculée. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -uint32_t armv7_shift(uint32_t x, unsigned int n, SRType type, unsigned int amount, bool carry) +bool armv7_shift(uint32_t x, unsigned int n, SRType type, unsigned int amount, bool carry, uint32_t *value) { - return armv7_shift_c(x, n, type, amount, &carry); + return armv7_shift_c(x, n, type, amount, &carry, value); } |