summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/pseudo.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/arm/v7/pseudo.c')
-rw-r--r--plugins/arm/v7/pseudo.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/plugins/arm/v7/pseudo.c b/plugins/arm/v7/pseudo.c
index 4055040..e50da2d 100644
--- a/plugins/arm/v7/pseudo.c
+++ b/plugins/arm/v7/pseudo.c
@@ -24,6 +24,7 @@
#include "pseudo.h"
+#include <assert.h>
#include <stddef.h>
@@ -470,6 +471,126 @@ bool armv7_thumb_expand_imm(uint32_t imm12, uint32_t *value)
/******************************************************************************
* *
+* Paramètres : op = encodage d'opération. *
+* cmode = détails quant au mode d'opération. *
+* imm8 = valeur sur 8 bits à étendre. *
+* value = nouvelle valeur calculée. [OUT] *
+* *
+* Description : Traduit la fonction 'AdvSIMDExpandImm'. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool armv7_advanced_simd_expand_imm(bool op, uint8_t cmode, uint8_t imm8, uint64_t *value)
+{
+ bool result; /* Bilan à retourner */
+ uint64_t raw; /* Valeur d'entrée sur 64 bits */
+ uint8_t cmode_31; /* Partie d'argument ciblée */
+ uint64_t imm8a; /* Valeur sur 8 bits #1 */
+ uint64_t imm8b; /* Valeur sur 8 bits #2 */
+ uint64_t imm8c; /* Valeur sur 8 bits #3 */
+ uint64_t imm8d; /* Valeur sur 8 bits #4 */
+ uint64_t imm8e; /* Valeur sur 8 bits #5 */
+ uint64_t imm8f; /* Valeur sur 8 bits #6 */
+ uint64_t imm8g; /* Valeur sur 8 bits #7 */
+ uint64_t imm8h; /* Valeur sur 8 bits #8 */
+ uint32_t imm32; /* Valeur sur 32 bits */
+
+ result = true;
+
+ raw = imm8;
+
+ cmode_31 = (cmode >> 1) & 0x7;
+
+ switch (cmode_31)
+ {
+ case b000:
+ *value = armv7_replicate_64(raw, 2);
+ break;
+
+ case b001:
+ *value = armv7_replicate_64(raw << 8, 2);
+ break;
+
+ case b010:
+ *value = armv7_replicate_64(raw << 16, 2);
+ break;
+
+ case b011:
+ *value = armv7_replicate_64(raw << 24, 2);
+ break;
+
+ case b100:
+ *value = armv7_replicate_64(raw, 4);
+ break;
+
+ case b101:
+ *value = armv7_replicate_64(raw << 8, 4);
+ break;
+
+ case b110:
+
+ if ((cmode & 0x1) == 0)
+ *value = armv7_replicate_64(raw << 8 | 0xff, 2);
+ else
+ *value = armv7_replicate_64(raw << 16 | 0xffff, 2);
+ break;
+
+ case b111:
+
+ if ((cmode & 0x1) == 0)
+ {
+ if (!op)
+ *value = armv7_replicate_64(raw, 8);
+
+ else
+ {
+ imm8a = armv7_replicate_8((imm8 & 0x80) >> 7, 8);
+ imm8b = armv7_replicate_8((imm8 & 0x40) >> 6, 8);
+ imm8c = armv7_replicate_8((imm8 & 0x20) >> 5, 8);
+ imm8d = armv7_replicate_8((imm8 & 0x10) >> 4, 8);
+ imm8e = armv7_replicate_8((imm8 & 0x8) >> 3, 8);
+ imm8f = armv7_replicate_8((imm8 & 0x4) >> 2, 8);
+ imm8g = armv7_replicate_8((imm8 & 0x2) >> 1, 8);
+ imm8h = armv7_replicate_8((imm8 & 0x1) >> 0, 8);
+
+ *value = (imm8a << 56) | (imm8b << 48) | (imm8c << 40) | (imm8d << 32) \
+ | (imm8e << 24) | (imm8f << 16) | (imm8g << 8) | imm8h;
+
+ }
+
+ }
+ else
+ {
+ if (!op)
+ {
+ imm32 = (raw & 0x80) << 31 \
+ | ((uint64_t)(raw & 0x40 ? 0 : 1)) << 30 \
+ | armv7_replicate_8((raw & 0x40) >> 6, 5) \
+ | ((raw & 0x3f) << 19);
+
+ *value = armv7_replicate_64(imm32, 2);
+
+ }
+
+ else
+ result = false;
+
+ }
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : type2 = type de décalage encodé sur 2 bits. *
* imm5 = valeur de décalage entière sur 5 bits. *
* type = type de décalage à constituer. [OUT] *
@@ -664,6 +785,72 @@ bool armv7_shift(uint32_t x, unsigned int n, SRType type, unsigned int amount, b
/******************************************************************************
* *
+* Paramètres : x = valeur sur 8 bits à traiter. *
+* n = nombre de partie à recopier. *
+* *
+* Description : Constitue une value à partir de réplications. *
+* *
+* Retour : Nouvelle valeur calculée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint8_t armv7_replicate_8(uint8_t x, unsigned int n)
+{
+ uint8_t result; /* Value à retourner */
+ unsigned int step; /* Marge de progression */
+ unsigned int i; /* Boucle de parcours */
+
+ assert(8 % n == 0);
+
+ result = 0;
+
+ step = 8 / n;
+
+ for (i = 0; i < 8; i += step)
+ result |= (x << (i * step));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : x = valeur sur 64 bits à traiter. *
+* n = nombre de partie à recopier. *
+* *
+* Description : Constitue une value à partir de réplications. *
+* *
+* Retour : Nouvelle valeur calculée. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+uint64_t armv7_replicate_64(uint64_t x, unsigned int n)
+{
+ uint64_t result; /* Value à retourner */
+ unsigned int step; /* Marge de progression */
+ unsigned int i; /* Boucle de parcours */
+
+ assert(64 % n == 0);
+
+ result = 0;
+
+ step = 64 / n;
+
+ for (i = 0; i < 64; i += step)
+ result |= (x << (i * step));
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : x = valeur sur 32 bits maximum à traiter. *
* n = nombre de bits à prendre en compte. *
* i = taille finale à obtenir. *