diff options
Diffstat (limited to 'src/arch/arm/v7')
227 files changed, 12960 insertions, 3116 deletions
diff --git a/src/arch/arm/v7/Makefile.am b/src/arch/arm/v7/Makefile.am index cea4dda..6f5362d 100644 --- a/src/arch/arm/v7/Makefile.am +++ b/src/arch/arm/v7/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libarcharmv7.la libarcharmv7_la_SOURCES = \ arm.h arm.c \ context.h context.c \ + cregister.h cregister.c \ fetch.h fetch.c \ helpers.h helpers.c \ instruction.h instruction.c \ diff --git a/src/arch/arm/v7/cregister.c b/src/arch/arm/v7/cregister.c new file mode 100644 index 0000000..62f3833 --- /dev/null +++ b/src/arch/arm/v7/cregister.c @@ -0,0 +1,212 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * cregisters.c - aides auxiliaires relatives aux registres de co-processeur ARMv7 + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "cregister.h" + + +#include <stdio.h> + + +#include "../register-int.h" + + + +/* Représentation d'un registre de co-processeur ARMv7 (instance) */ +struct _GArmV7CRegister +{ + GArmRegister parent; /* Instance parente */ + +}; + + +/* Représentation d'un registre de co-processeur ARMv7 (classe) */ +struct _GArmV7CRegisterClass +{ + GArmRegisterClass parent; /* Classe parente */ + +}; + + + +/* Initialise la classe des registres de co-processeur ARMv7. */ +static void g_armv7_cregister_class_init(GArmV7CRegisterClass *); + +/* Initialise une instance de registre de co-processeur ARMv7. */ +static void g_armv7_cregister_init(GArmV7CRegister *); + +/* Supprime toutes les références externes. */ +static void g_armv7_cregister_dispose(GArmV7CRegister *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_cregister_finalize(GArmV7CRegister *); + +/* Traduit un registre en version humainement lisible. */ +static void g_armv7_cregister_print(const GArmV7CRegister *, GBufferLine *, AsmSyntax); + + + +/* Indique le type défini pour une représentation d'un registre de co-processeur ARMv7. */ +G_DEFINE_TYPE(GArmV7CRegister, g_armv7_cregister, G_TYPE_ARM_REGISTER); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des registres de co-processeur ARMv7. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_cregister_class_init(GArmV7CRegisterClass *klass) +{ + GObjectClass *object_class; /* Autre version de la classe */ + GArchRegisterClass *reg_class; /* Classe de haut niveau */ + + object_class = G_OBJECT_CLASS(klass); + reg_class = G_ARCH_REGISTER_CLASS(klass); + + object_class->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_cregister_dispose; + object_class->finalize = (GObjectFinalizeFunc)g_armv7_cregister_finalize; + + reg_class->print = (reg_print_fc)g_armv7_cregister_print; + +} + + +/****************************************************************************** +* * +* Paramètres : reg = instance à initialiser. * +* * +* Description : Initialise une instance de registre de co-processeur ARMv7. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_cregister_init(GArmV7CRegister *reg) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : reg = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_cregister_dispose(GArmV7CRegister *reg) +{ + G_OBJECT_CLASS(g_armv7_cregister_parent_class)->dispose(G_OBJECT(reg)); + +} + + +/****************************************************************************** +* * +* Paramètres : reg = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_cregister_finalize(GArmV7CRegister *reg) +{ + G_OBJECT_CLASS(g_armv7_cregister_parent_class)->finalize(G_OBJECT(reg)); + +} + + +/****************************************************************************** +* * +* Paramètres : index = indice du registre correspondant. * +* * +* Description : Crée une réprésentation de registre de co-processeur ARMv7. * +* * +* Retour : Adresse de la structure mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArmV7CRegister *g_armv7_cregister_new(uint8_t index) +{ + GArmV7CRegister *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_CREGISTER, NULL); + + G_ARM_REGISTER(result)->index = index; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : reg = registre à transcrire. * +* line = ligne tampon où imprimer l'opérande donné. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit un registre en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_cregister_print(const GArmV7CRegister *reg, GBufferLine *line, AsmSyntax syntax) +{ + char key[MAX_REGNAME_LEN]; /* Mot clef principal */ + size_t klen; /* Taille de ce mot clef */ + + switch (G_ARM_REGISTER(reg)->index) + { + case 0 ... 15: + klen = snprintf(key, MAX_REGNAME_LEN, "c%hhu", G_ARM_REGISTER(reg)->index); + break; + default: + klen = snprintf(key, MAX_REGNAME_LEN, "c??"); + break; + } + + g_buffer_line_insert_text(line, BLC_ASSEMBLY, key, klen, RTT_REGISTER); + +} diff --git a/src/arch/arm/v7/cregister.h b/src/arch/arm/v7/cregister.h new file mode 100644 index 0000000..c0dfa7b --- /dev/null +++ b/src/arch/arm/v7/cregister.h @@ -0,0 +1,56 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * cregisters.h - prototypes pour les aides auxiliaires relatives aux registres de co-processeur ARMv7 + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_ARM_V7_CREGISTER_H +#define _ARCH_ARM_V7_CREGISTER_H + + +#include <glib-object.h> +#include <stdint.h> + + + +#define G_TYPE_ARMV7_CREGISTER g_armv7_cregister_get_type() +#define G_ARMV7_CREGISTER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_cregister_get_type(), GArmV7CRegister)) +#define G_IS_ARMV7_CREGISTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_cregister_get_type())) +#define G_ARMV7_CREGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_CREGISTER, GArmV7CRegisterClass)) +#define G_IS_ARMV7_CREGISTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_CREGISTER)) +#define G_ARMV7_CREGISTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_CREGISTER, GArmV7CRegisterClass)) + + +/* Représentation d'un registre de co-processeur ARMv7 (instance) */ +typedef struct _GArmV7CRegister GArmV7CRegister; + +/* Représentation d'un registre de co-processeur ARMv7 (classe) */ +typedef struct _GArmV7CRegisterClass GArmV7CRegisterClass; + + +/* Indique le type défini pour une représentation d'un registre de co-processeur ARMv7. */ +GType g_armv7_cregister_get_type(void); + +/* Crée une réprésentation de registre de co-processeur ARMv7. */ +GArmV7CRegister *g_armv7_cregister_new(uint8_t); + + + +#endif /* _ARCH_ARM_V7_CREGISTER_H */ diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c index 6ca98ca..206e6e6 100644 --- a/src/arch/arm/v7/fetch.c +++ b/src/arch/arm/v7/fetch.c @@ -368,7 +368,6 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst const mrange_t *range; /* Emplacementt d'instruction */ phys_t phys_pc; /* Position dans l'exécution */ GArchOperand *op; /* Opérande de surcouche */ - GArchOperand *sub_op; /* Opérande numérique en place */ uint32_t offset; /* Décallage encodé en dur */ bool ret; /* Bilan d'une récupération */ off_t val_offset; /* Position de valeur à lire */ @@ -411,11 +410,9 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst } op = g_arch_instruction_get_operand(instr, 1); - assert(G_IS_ARMV7_OFFSET_OPERAND(op)); + assert(G_IS_IMM_OPERAND(op)); - sub_op = g_armv7_offset_operand_get_value(G_ARMV7_OFFSET_OPERAND(op)); - - ret = g_imm_operand_get_value(G_IMM_OPERAND(sub_op), MDS_32_BITS_UNSIGNED, &offset); + ret = g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset); if (!ret) { assert(0); @@ -424,10 +421,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst /* Transformations et conservation d'une position de symbole */ - if (g_armv7_offset_operand_is_positive(G_ARMV7_OFFSET_OPERAND(op))) - val_offset = phys_pc + offset; - else - val_offset = phys_pc - offset; + val_offset = phys_pc + offset; if (!g_exe_format_translate_offset_into_vmpa(G_EXE_FORMAT(format), val_offset, &sym_addr)) { diff --git a/src/arch/arm/v7/helpers.h b/src/arch/arm/v7/helpers.h index 3b14837..c014682 100644 --- a/src/arch/arm/v7/helpers.h +++ b/src/arch/arm/v7/helpers.h @@ -25,18 +25,214 @@ #define _ARCH_ARM_V7_HELPERS_H +#include "cregister.h" #include "pseudo.h" +#include "operands/coproc.h" +#include "operands/estate.h" +#include "operands/limitation.h" #include "operands/maccess.h" #include "operands/offset.h" #include "operands/reglist.h" #include "operands/rotation.h" #include "operands/shift.h" +#include "../register.h" #include "../../operand.h" +#define BarrierLimitation(opt) \ + ({ \ + GArchOperand *__result; \ + __result = g_armv7_limitation_operand_new(opt); \ + __result; \ + }) + + +#define BitDiff(msb, lsb) \ + ({ \ + GArchOperand *__result; \ + uint32_t __width; \ + __width = g_imm_operand_get_raw_value(G_IMM_OPERAND(msb)); \ + __width -= g_imm_operand_get_raw_value(G_IMM_OPERAND(lsb)); \ + __width += 1; \ + __result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __width); \ + __result; \ + }) + + +#define BuildImm8(val) \ + ({ \ + GArchOperand *__result; \ + __result = g_imm_operand_new_from_value(MDS_8_BITS_UNSIGNED, (uint8_t)val); \ + __result; \ + }) + + +#define BuildImm16(val) \ + ({ \ + GArchOperand *__result; \ + __result = g_imm_operand_new_from_value(MDS_16_BITS_UNSIGNED, (uint16_t)val); \ + __result; \ + }) + + +#define CoProcessor(idx) \ + ({ \ + GArchOperand *__result; \ + __result = g_armv7_coproc_operand_new(idx); \ + __result; \ + }) + + +#define CRegister(idx) \ + ({ \ + GArchOperand *__result; \ + GArmV7CRegister *__reg; \ + __reg = g_armv7_cregister_new(idx); \ + if (__reg == NULL) \ + __result = NULL; \ + else \ + __result = g_register_operand_new(G_ARCH_REGISTER(__reg)); \ + __result; \ + }) + + +#define IncWidth(widthm1) \ + ({ \ + GArchOperand *__result; \ + uint32_t __width; \ + __width = widthm1 + 1; \ + __result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __width); \ + __result; \ + }) + + +#define DecodeImmShift(type, imm5) \ + ({ \ + GArchOperand *__result; \ + SRType __shift_t; \ + uint32_t __shift_n; \ + GArchOperand *__op_n; \ + if (!armv7_decode_imm_shift(type, imm5, &__shift_t, &__shift_n)) \ + __result = NULL; \ + else \ + { \ + __op_n = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __shift_n); \ + __result = g_armv7_shift_operand_new(__shift_t, __op_n); \ + } \ + __result; \ + }) + + +#define EndianState(big) \ + ({ \ + GArchOperand *__result; \ + __result = g_armv7_endian_operand_new(big); \ + __result; \ + }) + + +#define MakeMemoryAccess(base, off, shift, index, add, wback) \ + ({ \ + GArchOperand *__result; \ + GArchOperand *__offset; \ + if (off != NULL) \ + __offset = g_armv7_offset_operand_new(add, off); \ + else \ + __offset = NULL; \ + __result = g_armv7_maccess_operand_new(base, __offset, shift, index, wback); \ + __result; \ + }) + + +#define NextRegister(prev) \ + ({ \ + GRegisterOperand *__prev_op; \ + GArchRegister *__reg; \ + uint8_t __id; \ + __prev_op = G_REGISTER_OPERAND(prev); \ + __reg = g_register_operand_get_register(__prev_op); \ + __id = g_arm_register_get_index(G_ARM_REGISTER(__reg)); \ + Register(__id + 1); \ + }) + + +#define RawValue(val) \ + ({ \ + GArchOperand *__result; \ + __result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, (uint32_t)val); \ + __result; \ + }) + + +#define Register(idx) \ + ({ \ + GArchOperand *__result; \ + GArmV7Register *__reg; \ + __reg = g_armv7_register_new(idx); \ + if (__reg == NULL) \ + __result = NULL; \ + else \ + __result = g_register_operand_new(G_ARCH_REGISTER(__reg)); \ + __result; \ + }) + + +#define RegisterShift(shift_t, rs) \ + ({ \ + GArchOperand *__result; \ + GArchOperand *__reg; \ + __reg = Register(rs); \ + if (__reg == NULL) \ + __result = NULL; \ + else \ + __result = g_armv7_shift_operand_new(shift_t, __reg); \ + __result; \ + }) + + +#define Rotation(val5) \ + ({ \ + GArchOperand *__result; \ + uint8_t __rot; \ + GArchOperand *__rot_op; \ + __rot = val5; \ + __rot_op = g_imm_operand_new_from_value(MDS_8_BITS_UNSIGNED, __rot); \ + __result = g_armv7_rotation_operand_new(__rot_op); \ + if (__result == NULL) \ + g_object_unref(G_OBJECT(__rot_op)); \ + __result; \ + }) + + +#define UInt(val) \ + ({ \ + GArchOperand *__result; \ + __result = g_imm_operand_new_from_value(MDS_8_BITS_UNSIGNED, (uint8_t)val); \ + __result; \ + }) + + + + +//#define DecodeImmShift(raw_type, raw_imm5); +//g_armv7_shift_operand_new(SRType type, GArchOperand *value) + + + +//#define MakeMemoryAccess(base, off, shift, index, add, wback) NULL + +//g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool indexed, bool writeb) + +//g_armv7_offset_operand_new(add, off) + + + + +//////////////////// + #define Imm16(imm16) \ ({ \ GArchOperand *__result; \ @@ -105,23 +301,6 @@ __result; \ }) -#define DecodeImmShift(type, imm5) \ - ({ \ - GArchOperand *__result; \ - SRType __shift_t; \ - uint32_t __shift_n; \ - GArchOperand *__op_n; \ - if (!armv7_decode_imm_shift(type, imm5, &__shift_t, &__shift_n)) \ - __result = NULL; \ - else \ - { \ - __op_n = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, __shift_n); \ - __result = g_armv7_shift_operand_new(__shift_t, __op_n); \ - } \ - __result; \ - }) - - #if 0 // DecodeRegShift() @@ -137,12 +316,12 @@ return shift_t; -#define ZeroExtend(x, n, i) \ +#define ZeroExtend(x, i) \ ({ \ MemoryDataSize __mds; \ uint ## i ## _t __val; \ __mds = MDS_ ## i ## _BITS_UNSIGNED; \ - __val = armv7_zero_extend(x, n, i); \ + __val = armv7_zero_extend(x, 0/**/, i); \ g_imm_operand_new_from_value(__mds, __val); \ }) @@ -180,14 +359,14 @@ return shift_t; #define _MakeMemoryAccess(base, off, wr) \ MakeShiftedMemoryAccess(base, off, NULL, wr) - +/* #define MakeMemoryAccess(base, off, add, wr) \ ({ \ GArchOperand *__off; \ __off = MakeAccessOffset(add, off); \ _MakeMemoryAccess(base, __off, wr); \ }) - +*/ #define MakeMemoryNotIndexed(base, wr) \ _MakeMemoryAccess(base, NULL, wr) @@ -196,19 +375,6 @@ return shift_t; -#define BuildRotation(val5) \ - ({ \ - GArchOperand *__result; \ - uint8_t __rot; \ - GArchOperand *__rot_op; \ - __rot = val5; \ - __rot_op = g_imm_operand_new_from_value(MDS_8_BITS_UNSIGNED, __rot); \ - __result = g_armv7_rotation_operand_new(__rot_op); \ - if (__result == NULL) \ - g_object_unref(G_OBJECT(__rot_op)); \ - __result; \ - }) - @@ -266,7 +432,7 @@ GArchOperand *sign_extend_armv7_imm(uint32_t, bool, unsigned int); GArchOperand *thumb_expand_armv7_imm(uint32_t); /* Crée un opérande représentant un registre ARMv7. */ -GArchOperand *translate_armv7_register(uint8_t); +//GArchOperand *translate_armv7_register(uint8_t); /* Réalise un simple transtypage de valeur entière. */ GArchOperand *zero_extend_armv7_imm(uint32_t, unsigned int); diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h index c4cf3b2..ec8372a 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_arm.h @@ -1,24 +1,7 @@ #ifndef arm_def_tmp_h #define arm_def_tmp_h -#define armv7_read_arm_instr_adc_register_shifted_register(r) NULL -#define armv7_read_arm_instr_add_register_shifted_register(r) NULL -#define armv7_read_arm_instr_and_register_shifted_register(r) NULL -#define armv7_read_arm_instr_asr_register(r) NULL -#define armv7_read_arm_instr_bfc(r) NULL -#define armv7_read_arm_instr_bfi(r) NULL -#define armv7_read_arm_instr_bic_register_shifted_register(r) NULL -#define armv7_read_arm_instr_bkpt(r) NULL -#define armv7_read_arm_instr_bxj(r) NULL -#define armv7_read_arm_instr_cdp_cdp2(r) NULL -#define armv7_read_arm_instr_clrex(r) NULL -#define armv7_read_arm_instr_clz(r) NULL -#define armv7_read_arm_instr_cmn_register_shifted_register(r) NULL -#define armv7_read_arm_instr_cmp_register_shifted_register(r) NULL #define armv7_read_arm_instr_cps_arm(r) NULL -#define armv7_read_arm_instr_dbg(r) NULL #define armv7_read_arm_instr_dmd(r) NULL -#define armv7_read_arm_instr_dsb(r) NULL -#define armv7_read_arm_instr_eor_register_shifted_register(r) NULL #define armv7_read_arm_instr_eret(r) NULL #define armv7_read_arm_instr_hvc(r) NULL #define armv7_read_arm_instr_isb(r) NULL @@ -30,35 +13,7 @@ #define armv7_read_arm_instr_ldmib_ldmed(r) NULL #define armv7_read_arm_instr_ldm_ldmia_ldmfd_arm(r) NULL #define armv7_read_arm_instr_ldm_user_registers(r) NULL -#define armv7_read_arm_instr_ldrb_literal(r) NULL -#define armv7_read_arm_instr_ldrbt(r) NULL -#define armv7_read_arm_instr_ldrd_immediate(r) NULL -#define armv7_read_arm_instr_ldrd_literal(r) NULL -#define armv7_read_arm_instr_ldrd_register(r) NULL -#define armv7_read_arm_instr_ldrex(r) NULL -#define armv7_read_arm_instr_ldrexb(r) NULL -#define armv7_read_arm_instr_ldrexd(r) NULL -#define armv7_read_arm_instr_ldrexh(r) NULL -#define armv7_read_arm_instr_ldrh_immediate_arm(r) NULL -#define armv7_read_arm_instr_ldrh_literal(r) NULL -#define armv7_read_arm_instr_ldrh_register(r) NULL -#define armv7_read_arm_instr_ldrht(r) NULL #define armv7_read_arm_instr_ldr_register(r) NULL -#define armv7_read_arm_instr_ldrsb_immediate(r) NULL -#define armv7_read_arm_instr_ldrsb_literal(r) NULL -#define armv7_read_arm_instr_ldrsb_register(r) NULL -#define armv7_read_arm_instr_ldrsbt(r) NULL -#define armv7_read_arm_instr_ldrsh_immediate(r) NULL -#define armv7_read_arm_instr_ldrsh_literal(r) NULL -#define armv7_read_arm_instr_ldrsh_register(r) NULL -#define armv7_read_arm_instr_ldrsht(r) NULL -#define armv7_read_arm_instr_ldrt(r) NULL -#define armv7_read_arm_instr_lsl_register(r) NULL -#define armv7_read_arm_instr_lsr_register(r) NULL -#define armv7_read_arm_instr_mcr_mcr2(r) NULL -#define armv7_read_arm_instr_mcrr_mcrr2(r) NULL -#define armv7_read_arm_instr_mrc_mrc2(r) NULL -#define armv7_read_arm_instr_mrrc_mrrc2(r) NULL #define armv7_read_arm_instr_mrs(r) NULL #define armv7_read_arm_instr_mrs_banked_register(r) NULL #define armv7_read_arm_instr_msr_banked_register(r) NULL @@ -66,60 +21,17 @@ #define armv7_read_arm_instr_msr_immediate_b9(r) NULL #define armv7_read_arm_instr_msr_register_a8(r) NULL #define armv7_read_arm_instr_msr_register_b9(r) NULL -#define armv7_read_arm_instr_mvn_register_shifted_register(r) NULL -#define armv7_read_arm_instr_orr_register_shifted_register(r) NULL #define armv7_read_arm_instr_pkh(r) NULL #define armv7_read_arm_instr_pld_literal(r) NULL #define armv7_read_arm_instr_pld_pldw_immediate(r) NULL #define armv7_read_arm_instr_pld_pldw_register(r) NULL #define armv7_read_arm_instr_pli_immediate_literal(r) NULL #define armv7_read_arm_instr_pli_register(r) NULL -#define armv7_read_arm_instr_qadd(r) NULL -#define armv7_read_arm_instr_qadd16(r) NULL -#define armv7_read_arm_instr_qadd8(r) NULL -#define armv7_read_arm_instr_qasx(r) NULL -#define armv7_read_arm_instr_qdadd(r) NULL -#define armv7_read_arm_instr_qdsub(r) NULL -#define armv7_read_arm_instr_qsax(r) NULL -#define armv7_read_arm_instr_qsub(r) NULL -#define armv7_read_arm_instr_qsub16(r) NULL -#define armv7_read_arm_instr_qsub8(r) NULL -#define armv7_read_arm_instr_rbit(r) NULL -#define armv7_read_arm_instr_rev(r) NULL -#define armv7_read_arm_instr_rev16(r) NULL -#define armv7_read_arm_instr_revsh(r) NULL #define armv7_read_arm_instr_rfe(r) NULL -#define armv7_read_arm_instr_ror_immediate(r) NULL -#define armv7_read_arm_instr_ror_register(r) NULL -#define armv7_read_arm_instr_rrx(r) NULL -#define armv7_read_arm_instr_rsb_register_shifted_register(r) NULL -#define armv7_read_arm_instr_rsc_register_shifted_register(r) NULL -#define armv7_read_arm_instr_sadd16(r) NULL -#define armv7_read_arm_instr_sadd8(r) NULL -#define armv7_read_arm_instr_sasx(r) NULL -#define armv7_read_arm_instr_sbc_register_shifted_register(r) NULL -#define armv7_read_arm_instr_sbfx(r) NULL -#define armv7_read_arm_instr_sdiv(r) NULL -#define armv7_read_arm_instr_sel(r) NULL -#define armv7_read_arm_instr_sev(r) NULL -#define armv7_read_arm_instr_shadd16(r) NULL -#define armv7_read_arm_instr_shadd8(r) NULL -#define armv7_read_arm_instr_shasx(r) NULL -#define armv7_read_arm_instr_shsax(r) NULL -#define armv7_read_arm_instr_shsub16(r) NULL -#define armv7_read_arm_instr_shsub8(r) NULL #define armv7_read_arm_instr_smc_previously_smi(r) NULL #define armv7_read_arm_instr_smlabb_smlabt_smlatb_smlatt(r) NULL -#define armv7_read_arm_instr_smlad(r) NULL #define armv7_read_arm_instr_smlalbb_smlalbt_smlaltb_smlaltt(r) NULL -#define armv7_read_arm_instr_smlald(r) NULL #define armv7_read_arm_instr_smlawb_smlawt(r) NULL -#define armv7_read_arm_instr_smlsd(r) NULL -#define armv7_read_arm_instr_smlsld(r) NULL -#define armv7_read_arm_instr_smmla(r) NULL -#define armv7_read_arm_instr_smmls(r) NULL -#define armv7_read_arm_instr_smmul(r) NULL -#define armv7_read_arm_instr_smuad(r) NULL #define armv7_read_arm_instr_smulbb_smulbt_smultb_smultt(r) NULL #define armv7_read_arm_instr_smulwb_smulwt(r) NULL #define armv7_read_arm_instr_smusd(r) NULL @@ -148,45 +60,11 @@ #define armv7_read_arm_instr_str_register(r) NULL #define armv7_read_arm_instr_strt(r) NULL #define armv7_read_arm_instr_sub_register_shifted_register(r) NULL -#define armv7_read_arm_instr_svc_previously_swi(r) NULL -#define armv7_read_arm_instr_swp_swpb(r) NULL #define armv7_read_arm_instr_sxtab(r) NULL #define armv7_read_arm_instr_sxtab16(r) NULL #define armv7_read_arm_instr_sxtah(r) NULL #define armv7_read_arm_instr_sxtb(r) NULL #define armv7_read_arm_instr_sxtb16(r) NULL #define armv7_read_arm_instr_sxth(r) NULL -#define armv7_read_arm_instr_teq_register_shifted_register(r) NULL -#define armv7_read_arm_instr_tst_register_shifted_register(r) NULL -#define armv7_read_arm_instr_uadd16(r) NULL -#define armv7_read_arm_instr_uadd8(r) NULL -#define armv7_read_arm_instr_uasx(r) NULL -#define armv7_read_arm_instr_ubfx(r) NULL -#define armv7_read_arm_instr_udiv(r) NULL -#define armv7_read_arm_instr_uhadd16(r) NULL -#define armv7_read_arm_instr_uhadd8(r) NULL -#define armv7_read_arm_instr_uhasx(r) NULL -#define armv7_read_arm_instr_uhsax(r) NULL -#define armv7_read_arm_instr_uhsub16(r) NULL -#define armv7_read_arm_instr_uhsub8(r) NULL -#define armv7_read_arm_instr_uqadd16(r) NULL -#define armv7_read_arm_instr_uqadd8(r) NULL -#define armv7_read_arm_instr_uqasx(r) NULL -#define armv7_read_arm_instr_uqsax(r) NULL -#define armv7_read_arm_instr_uqsub16(r) NULL -#define armv7_read_arm_instr_uqsub8(r) NULL -#define armv7_read_arm_instr_usad8(r) NULL -#define armv7_read_arm_instr_usada8(r) NULL -#define armv7_read_arm_instr_usat(r) NULL -#define armv7_read_arm_instr_usat16(r) NULL -#define armv7_read_arm_instr_usax(r) NULL -#define armv7_read_arm_instr_usub16(r) NULL -#define armv7_read_arm_instr_usub8(r) NULL -#define armv7_read_arm_instr_uxtab(r) NULL -#define armv7_read_arm_instr_uxtab16(r) NULL -#define armv7_read_arm_instr_uxtah(r) NULL -#define armv7_read_arm_instr_uxtb16(r) NULL -#define armv7_read_arm_instr_uxth(r) NULL #define armv7_read_arm_instr_wfe(r) NULL -#define armv7_read_arm_instr_wfi(r) NULL #endif diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h index 8e8572d..1a62c43 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_16.h @@ -1,31 +1,13 @@ #ifndef thumb_16_def_tmp_h #define thumb_16_def_tmp_h -#define armv7_read_thumb_16_instr_asr_register(r) NULL -#define armv7_read_thumb_16_instr_bkpt(r) NULL #define armv7_read_thumb_16_instr_cps_thumb(r) NULL #define armv7_read_thumb_16_instr_it(r) NULL #define armv7_read_thumb_16_instr_ldm_ldmia_ldmfd_thumb(r) NULL -#define armv7_read_thumb_16_instr_ldrh_immediate_thumb(r) NULL -#define armv7_read_thumb_16_instr_ldrh_register(r) NULL -#define armv7_read_thumb_16_instr_ldrsb_register(r) NULL -#define armv7_read_thumb_16_instr_ldrsh_register(r) NULL -#define armv7_read_thumb_16_instr_lsl_register(r) NULL -#define armv7_read_thumb_16_instr_lsr_register(r) NULL -#define armv7_read_thumb_16_instr_rev(r) NULL -#define armv7_read_thumb_16_instr_rev16(r) NULL -#define armv7_read_thumb_16_instr_revsh(r) NULL -#define armv7_read_thumb_16_instr_ror_register(r) NULL -#define armv7_read_thumb_16_instr_setend(r) NULL -#define armv7_read_thumb_16_instr_sev(r) NULL #define armv7_read_thumb_16_instr_stm_stmia_stmea(r) NULL #define armv7_read_thumb_16_instr_strh_immediate_thumb(r) NULL #define armv7_read_thumb_16_instr_strh_register(r) NULL #define armv7_read_thumb_16_instr_str_register(r) NULL -#define armv7_read_thumb_16_instr_svc_previously_swi(r) NULL #define armv7_read_thumb_16_instr_sxtb(r) NULL #define armv7_read_thumb_16_instr_sxth(r) NULL -#define armv7_read_thumb_16_instr_udf(r) NULL -#define armv7_read_thumb_16_instr_uxth(r) NULL #define armv7_read_thumb_16_instr_wfe(r) NULL -#define armv7_read_thumb_16_instr_wfi(r) NULL #endif diff --git a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h index 1970369..c74ab49 100644 --- a/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h +++ b/src/arch/arm/v7/opcodes/opcodes_tmp_thumb_32.h @@ -1,18 +1,8 @@ #ifndef thumb_32_def_tmp_h #define thumb_32_def_tmp_h -#define armv7_read_thumb_32_instr_asr_register(r) NULL -#define armv7_read_thumb_32_instr_bfc(r) NULL -#define armv7_read_thumb_32_instr_bfi(r) NULL #define armv7_read_thumb_32_instr_b_mrs(r) NULL #define armv7_read_thumb_32_instr_b_msr_register(r) NULL -#define armv7_read_thumb_32_instr_bxj(r) NULL -#define armv7_read_thumb_32_instr_cdp_cdp2(r) NULL -#define armv7_read_thumb_32_instr_clrex(r) NULL -#define armv7_read_thumb_32_instr_clz(r) NULL #define armv7_read_thumb_32_instr_cps_thumb(r) NULL -#define armv7_read_thumb_32_instr_dbg(r) NULL -#define armv7_read_thumb_32_instr_dmb(r) NULL -#define armv7_read_thumb_32_instr_dsb(r) NULL #define armv7_read_thumb_32_instr_enterx_leavex(r) NULL #define armv7_read_thumb_32_instr_eret(r) NULL #define armv7_read_thumb_32_instr_hvc(r) NULL @@ -21,39 +11,10 @@ #define armv7_read_thumb_32_instr_ldc_ldc2_literal(r) NULL #define armv7_read_thumb_32_instr_ldmdb_ldmea(r) NULL #define armv7_read_thumb_32_instr_ldm_ldmia_ldmfd_thumb(r) NULL -#define armv7_read_thumb_32_instr_ldrb_literal(r) NULL -#define armv7_read_thumb_32_instr_ldrbt(r) NULL -#define armv7_read_thumb_32_instr_ldrd_immediate(r) NULL -#define armv7_read_thumb_32_instr_ldrd_literal(r) NULL -#define armv7_read_thumb_32_instr_ldrex(r) NULL -#define armv7_read_thumb_32_instr_ldrexb(r) NULL -#define armv7_read_thumb_32_instr_ldrexd(r) NULL -#define armv7_read_thumb_32_instr_ldrexh(r) NULL -#define armv7_read_thumb_32_instr_ldrh_immediate_thumb(r) NULL -#define armv7_read_thumb_32_instr_ldrh_literal(r) NULL -#define armv7_read_thumb_32_instr_ldrh_register(r) NULL -#define armv7_read_thumb_32_instr_ldrht(r) NULL -#define armv7_read_thumb_32_instr_ldrsb_immediate(r) NULL -#define armv7_read_thumb_32_instr_ldrsb_literal(r) NULL -#define armv7_read_thumb_32_instr_ldrsb_register(r) NULL -#define armv7_read_thumb_32_instr_ldrsbt(r) NULL -#define armv7_read_thumb_32_instr_ldrsh_immediate(r) NULL -#define armv7_read_thumb_32_instr_ldrsh_literal(r) NULL -#define armv7_read_thumb_32_instr_ldrsh_register(r) NULL -#define armv7_read_thumb_32_instr_ldrsht(r) NULL -#define armv7_read_thumb_32_instr_ldrt(r) NULL -#define armv7_read_thumb_32_instr_lsl_register(r) NULL -#define armv7_read_thumb_32_instr_lsr_register(r) NULL -#define armv7_read_thumb_32_instr_mcr_mcr2(r) NULL -#define armv7_read_thumb_32_instr_mcrr_mcrr2(r) NULL -#define armv7_read_thumb_32_instr_mrc_mrc2(r) NULL -#define armv7_read_thumb_32_instr_mrrc_mrrc2(r) NULL #define armv7_read_thumb_32_instr_mrs(r) NULL #define armv7_read_thumb_32_instr_mrs_banked_register(r) NULL #define armv7_read_thumb_32_instr_msr_banked_register(r) NULL #define armv7_read_thumb_32_instr_msr_register(r) NULL -#define armv7_read_thumb_32_instr_orn_immediate(r) NULL -#define armv7_read_thumb_32_instr_orn_register(r) NULL #define armv7_read_thumb_32_instr_pkh(r) NULL #define armv7_read_thumb_32_instr_pld_immediate(r) NULL #define armv7_read_thumb_32_instr_pld_literal(r) NULL @@ -62,43 +23,11 @@ #define armv7_read_thumb_32_instr_pld_register(r) NULL #define armv7_read_thumb_32_instr_pli_immediate_literal(r) NULL #define armv7_read_thumb_32_instr_pli_register(r) NULL -#define armv7_read_thumb_32_instr_qadd(r) NULL -#define armv7_read_thumb_32_instr_qdadd(r) NULL -#define armv7_read_thumb_32_instr_qdsub(r) NULL -#define armv7_read_thumb_32_instr_qsub(r) NULL -#define armv7_read_thumb_32_instr_rbit(r) NULL -#define armv7_read_thumb_32_instr_rev(r) NULL -#define armv7_read_thumb_32_instr_rev16(r) NULL -#define armv7_read_thumb_32_instr_revsh(r) NULL #define armv7_read_thumb_32_instr_rfe(r) NULL -#define armv7_read_thumb_32_instr_ror_immediate(r) NULL -#define armv7_read_thumb_32_instr_ror_register(r) NULL -#define armv7_read_thumb_32_instr_rrx(r) NULL -#define armv7_read_thumb_32_instr_sadd16(r) NULL -#define armv7_read_thumb_32_instr_sadd8(r) NULL -#define armv7_read_thumb_32_instr_sasx(r) NULL -#define armv7_read_thumb_32_instr_sbfx(r) NULL -#define armv7_read_thumb_32_instr_sdiv(r) NULL -#define armv7_read_thumb_32_instr_sel(r) NULL -#define armv7_read_thumb_32_instr_sev(r) NULL -#define armv7_read_thumb_32_instr_shadd16(r) NULL -#define armv7_read_thumb_32_instr_shadd8(r) NULL -#define armv7_read_thumb_32_instr_shasx(r) NULL -#define armv7_read_thumb_32_instr_shsax(r) NULL -#define armv7_read_thumb_32_instr_shsub16(r) NULL -#define armv7_read_thumb_32_instr_shsub8(r) NULL #define armv7_read_thumb_32_instr_smc_previously_smi(r) NULL #define armv7_read_thumb_32_instr_smlabb_smlabt_smlatb_smlatt(r) NULL -#define armv7_read_thumb_32_instr_smlad(r) NULL #define armv7_read_thumb_32_instr_smlalbb_smlalbt_smlaltb_smlaltt(r) NULL -#define armv7_read_thumb_32_instr_smlald(r) NULL #define armv7_read_thumb_32_instr_smlawb_smlawt(r) NULL -#define armv7_read_thumb_32_instr_smlsd(r) NULL -#define armv7_read_thumb_32_instr_smlsld(r) NULL -#define armv7_read_thumb_32_instr_smmla(r) NULL -#define armv7_read_thumb_32_instr_smmls(r) NULL -#define armv7_read_thumb_32_instr_smmul(r) NULL -#define armv7_read_thumb_32_instr_smuad(r) NULL #define armv7_read_thumb_32_instr_smulbb_smulbt_smultb_smultt(r) NULL #define armv7_read_thumb_32_instr_smulwb_smulwt(r) NULL #define armv7_read_thumb_32_instr_smusd(r) NULL @@ -137,36 +66,5 @@ #define armv7_read_thumb_32_instr_sxtb16(r) NULL #define armv7_read_thumb_32_instr_sxth(r) NULL #define armv7_read_thumb_32_instr_tbb_tbh(r) NULL -#define armv7_read_thumb_32_instr_uadd16(r) NULL -#define armv7_read_thumb_32_instr_uadd8(r) NULL -#define armv7_read_thumb_32_instr_uasx(r) NULL -#define armv7_read_thumb_32_instr_ubfx(r) NULL -#define armv7_read_thumb_32_instr_udf(r) NULL -#define armv7_read_thumb_32_instr_udiv(r) NULL -#define armv7_read_thumb_32_instr_uhadd16(r) NULL -#define armv7_read_thumb_32_instr_uhadd8(r) NULL -#define armv7_read_thumb_32_instr_uhasx(r) NULL -#define armv7_read_thumb_32_instr_uhsax(r) NULL -#define armv7_read_thumb_32_instr_uhsub16(r) NULL -#define armv7_read_thumb_32_instr_uhsub8(r) NULL -#define armv7_read_thumb_32_instr_uqadd16(r) NULL -#define armv7_read_thumb_32_instr_uqadd8(r) NULL -#define armv7_read_thumb_32_instr_uqasx(r) NULL -#define armv7_read_thumb_32_instr_uqsax(r) NULL -#define armv7_read_thumb_32_instr_uqsub16(r) NULL -#define armv7_read_thumb_32_instr_uqsub8(r) NULL -#define armv7_read_thumb_32_instr_usad8(r) NULL -#define armv7_read_thumb_32_instr_usada8(r) NULL -#define armv7_read_thumb_32_instr_usat(r) NULL -#define armv7_read_thumb_32_instr_usat16(r) NULL -#define armv7_read_thumb_32_instr_usax(r) NULL -#define armv7_read_thumb_32_instr_usub16(r) NULL -#define armv7_read_thumb_32_instr_usub8(r) NULL -#define armv7_read_thumb_32_instr_uxtab(r) NULL -#define armv7_read_thumb_32_instr_uxtab16(r) NULL -#define armv7_read_thumb_32_instr_uxtah(r) NULL -#define armv7_read_thumb_32_instr_uxtb16(r) NULL -#define armv7_read_thumb_32_instr_uxth(r) NULL #define armv7_read_thumb_32_instr_wfe(r) NULL -#define armv7_read_thumb_32_instr_wfi(r) NULL #endif diff --git a/src/arch/arm/v7/opdefs/Makefile.am b/src/arch/arm/v7/opdefs/Makefile.am index 607b27f..578e4a5 100644 --- a/src/arch/arm/v7/opdefs/Makefile.am +++ b/src/arch/arm/v7/opdefs/Makefile.am @@ -20,11 +20,22 @@ D2C_ENCODINGS = \ D2C_MACROS = \ -M SetFlags=g_armv7_instruction_define_setflags \ -M Condition=g_arm_instruction_set_cond \ - -M Register=translate_armv7_register \ -M "ExpandImmC32=g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, " \ -M SignExtend=sign_extend_armv7_imm \ - -M SetInsFlag=g_arch_instruction_set_flag + -M SetInsFlag=g_arch_instruction_set_flag \ + -M StoreCondition=g_arm_instruction_set_cond \ + -M ExtendKeyword=g_arch_instruction_extend_keyword +D2C_OPERANDS = \ + -n BarrierLimitation \ + -n BitDiff \ + -n IncWidth \ + -n DecodeImmShift \ + -n MakeMemoryAccess \ + -n Register \ + -n RegisterShift \ + -n UInt \ + -n ZeroExtend FIXED_C_INCLUDES = \ \n\#include \"..\/helpers.h\" \ @@ -44,62 +55,159 @@ FIXED_H_INCLUDES = \ \n\n +# for i in $(seq 1 426); do test -f *A88$i.d && (ls *A88$i.d | sed 's/^/\t/' | sed 's/$/\t\t\t\t\t\t\\/') ; done ARMV7_DEFS = \ adc_A881.d \ adc_A882.d \ + adc_A883.d \ add_A884.d \ add_A885.d \ add_A886.d \ add_A887.d \ + add_A888.d \ add_A889.d \ + add_A8810.d \ + add_A8811.d \ adr_A8812.d \ and_A8813.d \ and_A8814.d \ + and_A8815.d \ asr_A8816.d \ + asr_A8817.d \ b_A8818.d \ + bfc_A8819.d \ + bfi_A8820.d \ bic_A8821.d \ bic_A8822.d \ + bic_A8823.d \ + bkpt_A8824.d \ bl_A8825.d \ blx_A8826.d \ bx_A8827.d \ - cbnz_A8829.d \ + bxj_A8828.d \ + cb_A8829.d \ + cdp_A8830.d \ + clrex_A8832.d \ + clz_A8833.d \ cmn_A8834.d \ cmn_A8835.d \ + cmn_A8836.d \ cmp_A8837.d \ cmp_A8838.d \ + cmp_A8839.d \ + dbg_A8842.d \ + dmb_A8843.d \ + dsb_A8844.d \ eor_A8846.d \ eor_A8847.d \ + eor_A8848.d \ ldr_A8862.d \ ldr_A8863.d \ ldr_A8864.d \ ldr_A8865.d \ + ldr_A8866.d \ ldrb_A8867.d \ ldrb_A8868.d \ + ldrb_A8869.d \ ldrb_A8870.d \ + ldrbt_A8871.d \ + ldrd_A8872.d \ + ldrd_A8873.d \ + ldrd_A8874.d \ + ldrex_A8875.d \ + ldrexb_A8876.d \ + ldrexd_A8877.d \ + ldrexh_A8878.d \ + ldrh_A8879.d \ + ldrh_A8880.d \ + ldrh_A8881.d \ + ldrh_A8882.d \ + ldrht_A8883.d \ + ldrsb_A8884.d \ + ldrsb_A8885.d \ + ldrsb_A8886.d \ + ldrsbt_A8887.d \ + ldrsh_A8888.d \ + ldrsh_A8889.d \ + ldrsh_A8890.d \ + ldrsht_A8891.d \ + ldrt_A8892.d \ lsl_A8894.d \ + lsl_A8895.d \ lsr_A8896.d \ + lsr_A8897.d \ + mcr_A8898.d \ + mcrr_A8899.d \ mla_A88100.d \ mls_A88101.d \ mov_A88102.d \ mov_A88103.d \ mov_A88104.d \ movt_A88106.d \ + mrc_A88107.d \ + mrrc_A88108.d \ mul_A88114.d \ mvn_A88115.d \ mvn_A88116.d \ + mvn_A88117.d \ nop_A88119.d \ + orn_A88120.d \ + orn_A88121.d \ orr_A88122.d \ orr_A88123.d \ + orr_A88124.d \ pop_A88131.d \ pop_A88132.d \ push_A88133.d \ + qadd_A88134.d \ + qadd16_A88135.d \ + qadd8_A88136.d \ + qasx_A88137.d \ + qdadd_A88138.d \ + qdsub_A88139.d \ + qsax_A88140.d \ + qsub_A88141.d \ + qsub16_A88142.d \ + qsub8_A88143.d \ + rbit_A88144.d \ + rev_A88145.d \ + rev16_A88146.d \ + revsh_A88147.d \ + ror_A88149.d \ + ror_A88150.d \ + rrx_A88151.d \ rsb_A88152.d \ rsb_A88153.d \ + rsb_A88154.d \ rsc_A88155.d \ rsc_A88156.d \ + rsc_A88157.d \ + sadd16_A88158.d \ + sadd8_A88159.d \ + sasx_A88160.d \ sbc_A88161.d \ sbc_A88162.d \ + sbc_A88163.d \ + sbfx_A88164.d \ + sdiv_A88165.d \ + sel_A88166.d \ + setend_A88167.d \ + sev_A88168.d \ + shadd16_A88169.d \ + shadd8_A88170.d \ + shasx_A88171.d \ + shsax_A88172.d \ + shsub16_A88173.d \ + shsub8_A88174.d \ + smlad_A88177.d \ smlal_A88178.d \ + smlald_A88180.d \ + smlsd_A88182.d \ + smlsld_A88183.d \ + smmla_A88184.d \ + smmls_A88185.d \ + smmul_A88186.d \ + smuad_A88187.d \ smull_A88189.d \ str_A88203.d \ str_A88204.d \ @@ -110,16 +218,52 @@ ARMV7_DEFS = \ sub_A88222.d \ sub_A88223.d \ sub_A88225.d \ + svc_A88228.d \ + swp_A88229.d \ teq_A88237.d \ teq_A88238.d \ + teq_A88239.d \ tst_A88240.d \ tst_A88241.d \ + tst_A88242.d \ + uadd16_A88243.d \ + uadd8_A88244.d \ + uasx_A88245.d \ + ubfx_A88246.d \ + udf_A88247.d \ + udiv_A88248.d \ + uhadd16_A88249.d \ + uhadd8_A88250.d \ + uhasx_A88251.d \ + uhsax_A88252.d \ + uhsub16_A88253.d \ + uhsub8_A88254.d \ umaal_A88255.d \ umlal_A88256.d \ umull_A88257.d \ + uqadd16_A88258.d \ + uqadd8_A88259.d \ + uqasx_A88260.d \ + uqsax_A88261.d \ + uqsub16_A88262.d \ + uqsub8_A88263.d \ + usad8_A88264.d \ + usada8_A88265.d \ + usat_A88266.d \ + usat16_A88267.d \ + usax_A88268.d \ + usub16_A88269.d \ + usub8_A88270.d \ + uxtab_A88271.d \ + uxtab16_A88272.d \ + uxtah_A88273.d \ uxtb_A88274.d \ - yield_A88426.d \ - subs_B9320.d + uxtb16_A88275.d \ + uxth_A88276.d \ + wfi_A88425.d \ + yield_A88426.d + +# subs_B9320.d all: $(ARMV7_DEFS:.d=.g) fmk.done d2c_final_rules diff --git a/src/arch/arm/v7/opdefs/adc_A881.d b/src/arch/arm/v7/opdefs/adc_A881.d index ff37ea0..6bc66e2 100644 --- a/src/arch/arm/v7/opdefs/adc_A881.d +++ b/src/arch/arm/v7/opdefs/adc_A881.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,49 +23,52 @@ @title ADC (immediate) -@encoding(T1) { +@desc Add with Carry (immediate) adds an immediate value and the Carry flag value to a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word 1 1 1 1 0 i(1) 0 1 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <const> + @word 1 1 1 1 0 i(1) 0 1 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm(i:imm3:imm8) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) - @rules { + } - //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 1 0 1 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 0 1 0 1 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/adc_A882.d b/src/arch/arm/v7/opdefs/adc_A882.d index a43cadb..27ce6ad 100644 --- a/src/arch/arm/v7/opdefs/adc_A882.d +++ b/src/arch/arm/v7/opdefs/adc_A882.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,66 +23,70 @@ @title ADC (register) -@encoding(t1) { +@desc Add with Carry (register) adds a register value, the Carry flag value, and an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 0 1 0 1 Rm(3) Rdn(3) +@encoding (t1) { - @syntax <Rdn> <Rm> + @half 0 1 0 0 0 0 0 1 0 1 Rm(3) Rdn(3) - @conv { + @syntax "adcs" <reg_DN> <reg_M> - Rdn = Register(Rdn) - Rm = Register(Rm) + @conv { - } + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 1 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 1 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 1 0 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 0 1 0 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/adc_A883.d b/src/arch/arm/v7/opdefs/adc_A883.d new file mode 100644 index 0000000..a9c56d8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/adc_A883.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ADC (register-shifted register) + +@desc Add with Carry (register-shifted register) adds a register value, the Carry flag value, and a register-shifted register value. It writes the result to the destination register, and can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 1 0 1 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/add_A8810.d b/src/arch/arm/v7/opdefs/add_A8810.d new file mode 100644 index 0000000..2047276 --- /dev/null +++ b/src/arch/arm/v7/opdefs/add_A8810.d @@ -0,0 +1,83 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ADD (SP plus register, Thumb) + +@desc This instruction adds an optionally-shifted register value to the SP value, and writes the result to the destination register. + +@encoding (t1) { + + @half 0 1 0 0 0 1 0 0 DM(1) 1 1 0 1 Rdm(3) + + @syntax <reg_DM_1> <SP> <reg_DM_2> + + @conv { + + reg_DM_1 = Register(DM:Rdm) + reg_DM_2 = Register(DM:Rdm) + SP = Register(13) + + } + +} + +@encoding (t2) { + + @half 0 1 0 0 0 1 0 0 1 Rm(4) 1 0 1 + + @syntax <SP> <reg_M> + + @conv { + + reg_M = Register(Rm) + SP = Register(13) + + } + +} + +@encoding (T3) { + + @word 1 1 1 0 1 0 1 1 0 0 0 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + + @syntax <reg_D> <SP> <reg_M> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) + SP = Register(13) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") + + } + +} + diff --git a/src/arch/arm/v7/opdefs/add_A8811.d b/src/arch/arm/v7/opdefs/add_A8811.d new file mode 100644 index 0000000..5b6c0d1 --- /dev/null +++ b/src/arch/arm/v7/opdefs/add_A8811.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ADD (SP plus register, ARM) + +@desc This instruction adds an optionally-shifted register value to the SP value, and writes the result to the destination register. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 1 0 0 S(1) 1 1 0 1 Rd(4) imm5(5) type(2) 0 Rm(4) + + @syntax <reg_D> <SP> <reg_M> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) + SP = Register(13) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/add_A884.d b/src/arch/arm/v7/opdefs/add_A884.d index fb79567..8b624a7 100644 --- a/src/arch/arm/v7/opdefs/add_A884.d +++ b/src/arch/arm/v7/opdefs/add_A884.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,95 +23,76 @@ @title ADD (immediate, Thumb) -@encoding(t1) { +@desc This instruction adds an immediate value to a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 1 1 1 0 imm3(3) Rn(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rn> <const> + @half 0 0 0 1 1 1 0 imm3(3) Rn(3) Rd(3) - @conv { + @syntax "adds" <reg_D> <reg_N> <imm32> - Rd = Register(Rd) - Rn = Register(Rn) - const = ZeroExtend(imm3, 3, 32); + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm3, 32) - @rules { - - //setflags = !InITBlock(); - - } + } } -@encoding(t2) { - - @half 0 0 1 1 0 Rdn(3) imm8(8) - - @syntax <Rdn> <const> - - @conv { +@encoding (t2) { - Rdn = Register(Rdn) - const = ZeroExtend(imm8, 8, 32); + @half 0 0 1 1 0 Rdn(3) imm8(8) - } + @syntax "adds" <reg_DN> <imm32> - @rules { + @conv { - //setflags = !InITBlock(); + reg_DN = Register(Rdn) + imm32 = ZeroExtend(imm8, 32) - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @syntax {S} ".W" <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, i) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE CMN (immediate); - //if Rn == '1101' then SEE ADD (SP plus immediate); - //if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(T4) { +@encoding (T4) { - @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 Rn(4) 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 Rn(4) 0 imm3(3) Rd(4) imm8(8) - @syntax "addw" <Rd> <Rn> <const> + @syntax "addw" <reg_D> <reg_N> <imm32> - @conv { + @conv { - Rd = Register(Rd) - Rn = Register(Rn) - const = ZeroExtend(i:imm3:imm8, 12, 32) + reg_D = Register(Rd) + reg_N = Register(Rn) + imm32 = ZeroExtend(i:imm3:imm8, 32) - } - - @rules { - - //if Rn == '1111' then SEE ADR; - //if Rn == '1101' then SEE ADD (SP plus immediate); - //setflags = FALSE - //if d IN {13,15} then UNPREDICTABLE; - - } + } } + diff --git a/src/arch/arm/v7/opdefs/add_A885.d b/src/arch/arm/v7/opdefs/add_A885.d index d3220c5..0f4a919 100644 --- a/src/arch/arm/v7/opdefs/add_A885.d +++ b/src/arch/arm/v7/opdefs/add_A885.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,28 +23,29 @@ @title ADD (immediate, ARM) -@encoding(A1) { +@desc This instruction adds an immediate value to a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word cond(4) 0 0 1 0 1 0 0 S(1) Rn(4) Rd(4) imm12(12) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rn> <const> + @word cond(4) 0 0 1 0 1 0 0 S(1) Rn(4) Rd(4) imm12(12) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) - @rules { + } - //if ((Rn == '1111') && (S == '0')) ; see ADR - //if (Rn == '1101') ; see ADD (SP plus immediate) - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/add_A886.d b/src/arch/arm/v7/opdefs/add_A886.d index fd8f7a4..e4f9e00 100644 --- a/src/arch/arm/v7/opdefs/add_A886.d +++ b/src/arch/arm/v7/opdefs/add_A886.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,68 +23,61 @@ @title ADD (register, Thumb) -@encoding(t1) { +@desc This instruction adds a register value and an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 1 1 0 0 Rm(3) Rn(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rn> <Rm> + @half 0 0 0 1 1 0 0 Rm(3) Rn(3) Rd(3) - @conv { + @syntax "adds" <reg_D> <reg_N> <reg_M> - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) -} - -@encoding(t2) { - - @half 0 1 0 0 0 1 0 0 DN(1) Rm(4) Rdn(3) + } - @syntax <Rdn> <Rm> +} - @conv { +@encoding (t2) { - Rdn = Register(DN:Rdn) - Rm = Register(Rm) + @half 0 1 0 0 0 1 0 0 DN(1) Rm(4) Rdn(3) - } + @syntax <reg_DN> <reg_M> - @rules { + @conv { - //if (DN:Rdn) == '1101' || Rm == '1101' then SEE ADD (SP plus register); - //if n == 15 && m == 15 then UNPREDICTABLE; - //if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; + reg_DN = Register(DN:Rdn) + reg_M = Register(Rm) - } + } } -@encoding(T3) { - - @word 1 1 1 0 1 0 1 1 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) +@encoding (T3) { - @syntax {S} ".W" <Rd> <Rn> <Rm> <?shift> + @word 1 1 1 0 1 0 1 1 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <?shift> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - @rules { + } - //if Rd == '1111' && S == '1' then SEE CMN (register); - //if Rn == '1101' then SEE ADD (SP plus register); - //if d == 13 || (d == 15 && S == '0') || n == 15 || m IN {13,15} then UNPREDICTABLE; + @rules { + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } + diff --git a/src/arch/arm/v7/opdefs/add_A887.d b/src/arch/arm/v7/opdefs/add_A887.d index 17bbe7f..18400a6 100644 --- a/src/arch/arm/v7/opdefs/add_A887.d +++ b/src/arch/arm/v7/opdefs/add_A887.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,28 +23,30 @@ @title ADD (register, ARM) -@encoding(A1) { +@desc This instruction adds a register value and an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word cond(4) 0 0 0 0 1 0 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @word cond(4) 0 0 0 0 1 0 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <?shift> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - @rules { + } - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions - //if Rn == '1101' then SEE ADD (SP plus register); + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/add_A888.d b/src/arch/arm/v7/opdefs/add_A888.d new file mode 100644 index 0000000..5549145 --- /dev/null +++ b/src/arch/arm/v7/opdefs/add_A888.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ADD (register-shifted register) + +@desc Add (register-shifted register) adds a register value and a register-shifted register value. It writes the result to the destination register, and can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 1 0 0 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/add_A889.d b/src/arch/arm/v7/opdefs/add_A889.d index 3c9d432..5fab17c 100644 --- a/src/arch/arm/v7/opdefs/add_A889.d +++ b/src/arch/arm/v7/opdefs/add_A889.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,117 +23,101 @@ @title ADD (SP plus immediate) -@encoding(t1) { +@desc This instruction adds an immediate value to the SP value, and writes the result to the destination register. - @half 1 0 1 0 1 Rd(3) imm8(8) +@encoding (t1) { - @syntax <Rd> <SP> <const> + @half 1 0 1 0 1 Rd(3) imm8(8) - @conv { + @syntax <reg_D> <SP> <imm32> - Rd = Register(Rd) - SP = Register(13) - const = ZeroExtend(imm8:'00', 10, 32); + @conv { - } + reg_D = Register(Rd) + imm32 = ZeroExtend(imm8:'00', 32) + SP = Register(13) - @rules { - - //setflags = FALSE - - } + } } -@encoding(t2) { - - @half 1 0 1 1 0 0 0 0 0 imm7(7) - - @syntax <SP1> <SP2> <const> - - @conv { +@encoding (t2) { - SP1 = Register(13) - SP2 = Register(13) - const = ZeroExtend(imm7:'00', 9, 32); + @half 1 0 1 1 0 0 0 0 0 imm7(7) - } + @syntax <SP_0> <SP_1> <imm32> - @rules { + @conv { - //setflags = FALSE + imm32 = ZeroExtend(imm7:'00', 32) + SP_0 = Register(13) + SP_1 = Register(13) - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) - @syntax {S} ".W" <Rd> <SP> <const> + @syntax <reg_D> <SP> <imm32> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - SP = Register(13) - const = ThumbExpandImm_C(i:imm3:imm8, i) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) + SP = Register(13) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE CMN (immediate); - //if d == 15 && S == '0' then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(T4) { +@encoding (T4) { - @word 1 1 1 1 0 i(1) 0 1 0 0 0 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 1 1 0 1 0 imm3(3) Rd(4) imm8(8) - @syntax "addw" <Rd> <SP> <const> + @syntax "addw" <reg_D> <SP> <imm32> - @conv { + @conv { - Rd = Register(Rd) - SP = Register(13) - const = ZeroExtend(i:imm3:imm8, 12, 32) + reg_D = Register(Rd) + imm32 = ZeroExtend(i:imm3:imm8, 32) + SP = Register(13) - } - - @rules { - - //if Rd == '1111' && S == '1' then SEE CMN (immediate); - //if d == 15 && S == '0' then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 1 0 0 S(1) 1 1 0 1 Rd(4) imm12(12) + @word cond(4) 0 0 1 0 1 0 0 S(1) 1 1 0 1 Rd(4) imm12(12) - @syntax {S} {c} <Rd> <SP> <const> + @syntax <reg_D> <SP> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - SP = Register(13) - const = ARMExpandImm(imm12) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) + SP = Register(13) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/adr_A8812.d b/src/arch/arm/v7/opdefs/adr_A8812.d index 38ad6af..16615cb 100644 --- a/src/arch/arm/v7/opdefs/adr_A8812.d +++ b/src/arch/arm/v7/opdefs/adr_A8812.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,94 +23,92 @@ @title ADR -@encoding(t1) { +@desc This instruction adds an immediate value to the PC value to form a PC-relative address, and writes the result to the destination register. - @half 1 0 1 0 0 Rd(3) imm8(8) +@encoding (t1) { - @syntax "add" <Rd> <PC> <imm32> + @half 1 0 1 0 0 Rd(3) imm8(8) - @conv { + @syntax <reg_D> <imm32> - Rd = Register(Rd) - PC = Register(15) - imm32 = ZeroExtend(imm8:'00', 10, 32) + @conv { - } + reg_D = Register(Rd) + imm32 = ZeroExtend(imm8:'00', 32) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 1 1 1 1 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 1 1 1 1 0 imm3(3) Rd(4) imm8(8) - @syntax "sub" <Rd> <PC> <imm32> + @syntax ".W" <reg_D> <imm32> - @conv { + @conv { - Rd = Register(Rd) - PC = Register(15) - imm32 = ZeroExtend(i:imm3:imm8, 12, 32) + reg_D = Register(Rd) + imm32 = ZeroExtend(i:imm3:imm8, 32) - } + } - @rules { +} - //if d IN {13,15} then UNPREDICTABLE; +@encoding (T3) { - } + @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 1 1 1 1 0 imm3(3) Rd(4) imm8(8) -} + @syntax ".W" <reg_D> <imm32> -@encoding(T3) { + @conv { - @word 1 1 1 1 0 i(1) 1 0 0 0 0 0 1 1 1 1 0 imm3(3) Rd(4) imm8(8) + reg_D = Register(Rd) + imm32 = ZeroExtend(i:imm3:imm8, 32) - @syntax "add" <Rd> <PC> <imm32> + } - @conv { +} - Rd = Register(Rd) - PC = Register(15) - imm32 = ZeroExtend(i:imm3:imm8, 12, 32) +@encoding (A1) { - } + @word cond(4) 0 0 1 0 1 0 0 0 1 1 1 1 Rd(4) imm12(12) - @rules { + @syntax <reg_D> <imm32> - //if d IN {13,15} then UNPREDICTABLE; + @conv { - } + reg_D = Register(Rd) + imm32 = ARMExpandImm(imm12) -} + } -@encoding(A1) { + @rules { - @word cond(4) 0 0 1 0 1 0 0 0 1 1 1 1 Rd(4) imm12(12) + chk_call StoreCondition(cond) - @syntax "add" <Rd> <PC> <const> + } - @conv { +} - Rd = Register(Rd) - PC = Register(15) - const = ARMExpandImm(imm12) +@encoding (A2) { - } + @word cond(4) 0 0 1 0 0 1 0 0 1 1 1 1 Rd(4) imm12(12) -} + @syntax <reg_D> <imm32> -@encoding(A2) { + @conv { - @word cond(4) 0 0 1 0 0 1 0 0 1 1 1 1 Rd(4) imm12(12) + reg_D = Register(Rd) + imm32 = ARMExpandImm(imm12) - @syntax "sub" <Rd> <PC> <const> + } - @conv { + @rules { - Rd = Register(Rd) - PC = Register(15) - const = ARMExpandImm(imm12) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/and_A8813.d b/src/arch/arm/v7/opdefs/and_A8813.d index f0a1740..3e1d0ed 100644 --- a/src/arch/arm/v7/opdefs/and_A8813.d +++ b/src/arch/arm/v7/opdefs/and_A8813.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,50 +23,52 @@ @title AND (immediate) -@encoding(T1) { +@desc This instruction performs a bitwise AND of a register value and an immediate value, and writes the result to the destination register. - @word 1 1 1 1 0 i(1) 0 0 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <const> + @word 1 1 1 1 0 i(1) 0 0 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - //if ((Rd == '1111') && (S == '1')) ; see TST (immediate) - //if ((d == 13) || ((d == 15) && (S == '0')) || (n IN {13,15})) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 0 0 0 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 0 0 0 0 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm_C(imm12, 0) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm_C(imm12, 0) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/and_A8814.d b/src/arch/arm/v7/opdefs/and_A8814.d index 10593a0..77f7e55 100644 --- a/src/arch/arm/v7/opdefs/and_A8814.d +++ b/src/arch/arm/v7/opdefs/and_A8814.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,67 +23,70 @@ @title AND (register) -@encoding(t1) { +@desc This instruction performs a bitwise AND of a register value and an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 0 0 0 0 Rm(3) Rdn(3) +@encoding (t1) { - @syntax <Rdn> <Rm> + @half 0 1 0 0 0 0 0 0 0 0 Rm(3) Rdn(3) - @conv { + @syntax "ands" <reg_DN> <reg_M> - Rdn = Register(Rdn) - Rm = Register(Rm) + @conv { - } + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 0 0 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see TST (register) - //if ((d == 13) || ((d == 15) && (S == '0')) || (n IN {13,15})) ; unpredictable + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 0 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 0 0 0 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/and_A8815.d b/src/arch/arm/v7/opdefs/and_A8815.d new file mode 100644 index 0000000..5ace3fa --- /dev/null +++ b/src/arch/arm/v7/opdefs/and_A8815.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title AND (register-shifted register) + +@desc This instruction performs a bitwise AND of a register value and a register-shifted register value. It writes the result to the destination register, and can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 0 0 0 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/asr_A8816.d b/src/arch/arm/v7/opdefs/asr_A8816.d index 7c1fda6..006a26c 100644 --- a/src/arch/arm/v7/opdefs/asr_A8816.d +++ b/src/arch/arm/v7/opdefs/asr_A8816.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,71 +23,69 @@ @title ASR (immediate) -@encoding(t1) { +@desc Arithmetic Shift Right (immediate) shifts a register value right by an immediate number of bits, shifting in copies of its sign bit, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 1 0 imm5(5) Rm(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rm> <#imm> + @half 0 0 0 1 0 imm5(5) Rm(3) Rd(3) - @conv { + @syntax "asrs" <reg_D> <reg_M> <shift_imm> - Rd = Register(Rd) - Rm = Register(Rm) - imm = FixedShift(2, imm5) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) + shift_imm = DecodeImmShift('10', imm5) - @rules { - - //setflags = !InITBlock(); - - } + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 1 0 Rm(4) + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 1 0 Rm(4) - @syntax {S} ".W" <Rd> <Rm> <#imm> + @syntax <reg_D> <reg_M> <shift_imm> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rm = Register(Rm) - imm = FixedShift(2, imm3:imm2) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('10', imm3:imm2) - } + } - @rules { + @rules { - //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 1 0 0 Rm(4) + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 1 0 0 Rm(4) - @syntax {S} {c} <Rd> <Rm> <#imm> + @syntax <reg_D> <reg_M> <shift_imm> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rm = Register(Rm) - imm = FixedShift(2, imm5) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('10', imm5) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/asr_A8817.d b/src/arch/arm/v7/opdefs/asr_A8817.d new file mode 100644 index 0000000..1e1e9c1 --- /dev/null +++ b/src/arch/arm/v7/opdefs/asr_A8817.d @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ASR (register) + +@desc Arithmetic Shift Right (register) shifts a register value right by a variable number of bits, shifting in copies of its sign bit, and writes the result to the destination register. The variable number of bits is read from the bottom byte of a register. It can optionally update the condition flags based on the result. + +@encoding (t1) { + + @half 0 1 0 0 0 0 0 1 0 0 Rm(3) Rdn(3) + + @syntax "asrs" <reg_DN> <reg_M> + + @conv { + + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 0 1 0 S(1) Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) Rm(4) 0 1 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/b_A8818.d b/src/arch/arm/v7/opdefs/b_A8818.d index 55b123e..9e27753 100644 --- a/src/arch/arm/v7/opdefs/b_A8818.d +++ b/src/arch/arm/v7/opdefs/b_A8818.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,153 +23,135 @@ @title B -@encoding(t1) { +@desc Branch causes a branch to a target address. - @half 1 1 0 1 cond(4) imm8(8) +@encoding (t1) { - @syntax {c} <label> + @half 1 1 0 1 cond(4) imm8(8) - @conv { + @syntax <imm32> - c = Condition(cond) - label = SignExtend(imm8:'0', imm8 & 0x80, 32) + @conv { - } + imm32 = SignExtend(imm8:'0', imm8 & 0x80, 32) - @hooks { + } - fetch = help_fetching_with_instruction_b_from_thumb - link = handle_arm_conditional_branch_as_link - post = post_process_branch_instructions + @rules { - } + chk_call StoreCondition(cond) - @rules { + } - //if cond == '1110' then UNDEFINED; - //if cond == '1111' then SEE SVC; - //chk_call SetInsFlag(AIF_RETURN_POINT) + @hooks { - } + fetch = help_fetching_with_instruction_b_from_thumb + link = handle_arm_conditional_branch_as_link + post = post_process_branch_instructions -} - -@encoding(t2) { + } - @half 1 1 1 0 0 imm11(11) - - @syntax <label> +} - @conv { +@encoding (t2) { - label = SignExtend(imm11:'0', imm11 & 0x400, 32) + @half 1 1 1 0 0 imm11(11) - } + @syntax <imm32> - @hooks { + @conv { - fetch = help_fetching_with_instruction_b_from_thumb - link = handle_arm_conditional_branch_as_link - post = post_process_branch_instructions + imm32 = SignExtend(imm11:'0', imm11 & 0x400, 32) - } + } - @rules { + @hooks { - //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - //chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_b_from_thumb + link = handle_arm_conditional_branch_as_link + post = post_process_branch_instructions - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 1 0 S(1) cond(4) imm6(6) 1 0 J1(1) 0 J2(1) imm11(11) + @word 1 1 1 1 0 S(1) cond(4) imm6(6) 1 0 J1(1) 0 J2(1) imm11(11) - @syntax {c} ".W" <label> + @syntax ".W" <imm32> - @conv { + @conv { - c = Condition(cond) - label = SignExtend(S:J2:J1:imm6:imm11:'0', S, 32) + imm32 = SignExtend(S:J2:J1:imm6:imm11:'0', S & 0x1, 32) - } + } - @hooks { + @rules { - fetch = help_fetching_with_instruction_b_from_thumb - link = handle_arm_conditional_branch_as_link - post = post_process_branch_instructions + chk_call StoreCondition(cond) - } + } - @rules { + @hooks { - //if cond<3:1> == '111' then SEE "Related encodings"; - //if InITBlock() then UNPREDICTABLE; - //chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_b_from_thumb + link = handle_arm_conditional_branch_as_link + post = post_process_branch_instructions - } + } } -@encoding(T4) { +@encoding (T4) { - @word 1 1 1 1 0 S(1) imm10(10) 1 0 J1(1) 1 J2(1) imm11(11) + @word 1 1 1 1 0 S(1) imm10(10) 1 0 J1(1) 1 J2(1) imm11(11) - @syntax "b.W" <label> + @syntax ".W" <imm32> - @conv { + @conv { - I1 = NOT(J1 EOR S) - I2 = NOT(J2 EOR S) - label = SignExtend(S:I1:I2:imm10:imm11:'0', S, 32) + I1 = NOT(J1 EOR S) + I2 = NOT(J2 EOR S) + imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', S & 0x1, 32) - } + } - @hooks { + @hooks { - fetch = help_fetching_with_instruction_b_from_thumb - link = handle_arm_conditional_branch_as_link - post = post_process_branch_instructions + fetch = help_fetching_with_instruction_b_from_thumb + link = handle_arm_conditional_branch_as_link + post = post_process_branch_instructions - } - - @rules { - - //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - //chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 1 0 1 0 imm24(24) + @word cond(4) 1 0 1 0 imm24(24) - @syntax {c} <label> + @syntax <imm32> - @conv { + @conv { - c = Condition(cond) - label = SignExtend(imm24:'00', imm24 & 0x800000, 32) + imm32 = SignExtend(imm24:'00', imm24 & 0x800000, 32) - } + } - @hooks { + @rules { - fetch = help_fetching_with_instruction_b_from_arm - link = handle_arm_conditional_branch_as_link - post = post_process_branch_instructions + chk_call StoreCondition(cond) - } + } - @rules { + @hooks { - //chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_b_from_arm + link = handle_arm_conditional_branch_as_link + post = post_process_branch_instructions - } + } } + diff --git a/src/arch/arm/v7/opdefs/bfc_A8819.d b/src/arch/arm/v7/opdefs/bfc_A8819.d new file mode 100644 index 0000000..0ee99c8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/bfc_A8819.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title BFC + +@desc Bit Field Clear clears any number of adjacent bits at any position in a register, without affecting the other bits in the register. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 0 1 1 0 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 0 msb(5) + + @syntax <reg_D> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + msbit = UInt(msb) + lsbit = UInt(imm3:imm2) + width = BitDiff(msbit, lsbit) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 1 1 0 msb(5) Rd(4) lsb(5) 0 0 1 1 1 1 1 + + @syntax <reg_D> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + msbit = UInt(msb) + lsbit = UInt(lsb) + width = BitDiff(msbit, lsbit) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/bfi_A8820.d b/src/arch/arm/v7/opdefs/bfi_A8820.d new file mode 100644 index 0000000..1d2bb2f --- /dev/null +++ b/src/arch/arm/v7/opdefs/bfi_A8820.d @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title BFI + +@desc Bit Field Insert copies any number of low order bits from a register into the same number of adjacent bits at any position in the destination register. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 0 1 1 0 Rn(4) 0 imm3(3) Rd(4) imm2(2) 0 msb(5) + + @syntax <reg_D> <reg_N> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + msbit = UInt(msb) + lsbit = UInt(imm3:imm2) + width = BitDiff(msbit, lsbit) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 1 1 0 msb(5) Rd(4) lsb(5) 0 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + msbit = UInt(msb) + lsbit = UInt(lsb) + width = BitDiff(msbit, lsbit) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/bic_A8821.d b/src/arch/arm/v7/opdefs/bic_A8821.d index 6f5bd46..9171b69 100644 --- a/src/arch/arm/v7/opdefs/bic_A8821.d +++ b/src/arch/arm/v7/opdefs/bic_A8821.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,49 +23,52 @@ @title BIC (immediate) -@encoding(T1) { +@desc Bitwise Bit Clear (immediate) performs a bitwise AND of a register value and the complement of an immediate value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word 1 1 1 1 0 i(1) 0 0 0 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <const> + @word 1 1 1 1 0 i(1) 0 0 0 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 1 1 1 0 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 1 1 1 0 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm_C(imm12, 0) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm_C(imm12, 0) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/bic_A8822.d b/src/arch/arm/v7/opdefs/bic_A8822.d index 03f7948..8503460 100644 --- a/src/arch/arm/v7/opdefs/bic_A8822.d +++ b/src/arch/arm/v7/opdefs/bic_A8822.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,66 +23,70 @@ @title BIC (register) -@encoding(t1) { +@desc Bitwise Bit Clear (register) performs a bitwise AND of a register value and the complement of an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 1 1 1 0 Rm(3) Rdn(3) +@encoding (t1) { - @syntax <Rdn> <Rm> + @half 0 1 0 0 0 0 1 1 1 0 Rm(3) Rdn(3) - @conv { + @syntax "bics" <reg_DN> <reg_M> - Rdn = Register(Rdn) - Rm = Register(Rm) + @conv { - } + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 0 0 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 1 1 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 1 1 1 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/bic_A8823.d b/src/arch/arm/v7/opdefs/bic_A8823.d new file mode 100644 index 0000000..e6903db --- /dev/null +++ b/src/arch/arm/v7/opdefs/bic_A8823.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title BIC (register-shifted register) + +@desc Bitwise Bit Clear (register-shifted register) performs a bitwise AND of a register value and the complement of a register-shifted register value. It writes the result to the destination register, and can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 1 0 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/bkpt_A8824.d b/src/arch/arm/v7/opdefs/bkpt_A8824.d new file mode 100644 index 0000000..f0aa13a --- /dev/null +++ b/src/arch/arm/v7/opdefs/bkpt_A8824.d @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title BKPT + +@desc Breakpoint causes a software breakpoint to occur. Breakpoint is always unconditional, even when inside an IT block. + +@encoding (t1) { + + @half 1 0 1 1 1 1 1 0 imm8(8) + + @syntax <imm32> + + @conv { + + imm32 = ZeroExtend(imm8, 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 0 1 0 imm12(12) 0 1 1 1 imm4(4) + + @syntax <imm32> + + @conv { + + imm32 = ZeroExtend(imm12:imm4, 32) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/bl_A8825.d b/src/arch/arm/v7/opdefs/bl_A8825.d index c2eb7bd..da0def4 100644 --- a/src/arch/arm/v7/opdefs/bl_A8825.d +++ b/src/arch/arm/v7/opdefs/bl_A8825.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,118 +23,103 @@ @title BL, BLX (immediate) -@encoding(T1) { +@desc Branch with Link calls a subroutine at a PC-relative address. Branch with Link and Exchange Instruction Sets (immediate) calls a subroutine at a PC-relative address, and changes instruction set from ARM to Thumb, or from Thumb to ARM. - @word 1 1 1 1 0 S(1) imm10(10) 1 1 J1(1) 1 J2(1) imm11(11) +@encoding (T1) { - @syntax <imm32> + @word 1 1 1 1 0 S(1) imm10(10) 1 1 J1(1) 1 J2(1) imm11(11) - @conv { + @syntax <imm32> - I1 = NOT(J1 EOR S) - I2 = NOT(J2 EOR S) - imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', S, 32) + @conv { - } + I1 = NOT(J1 EOR S) + I2 = NOT(J2 EOR S) + imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', S & 0x1, 32) - @hooks { + } - fetch = help_fetching_with_instruction_bl_from_thumb - link = handle_call_as_link - post = post_process_branch_and_link_instructions + @hooks { - } + fetch = help_fetching_with_instruction_bl_from_thumb + link = handle_call_as_link + post = post_process_branch_and_link_instructions - @rules { - - //chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(T2) { - - @word 1 1 1 1 0 S(1) imm10H(10) 1 1 J1(1) 0 J2(1) imm10L(10) H(1) - - @syntax "blx" <imm32> - - @conv { +@encoding (T2) { - I1 = NOT(J1 EOR S) - I2 = NOT(J2 EOR S) - imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', S, 32) + @word 1 1 1 1 0 S(1) imm10H(10) 1 1 J1(1) 0 J2(1) imm10L(10) H(1) - } + @syntax "blx" <imm32> - @hooks { + @conv { - fetch = help_fetching_with_instruction_blx_from_thumb - link = handle_call_as_link - post = post_process_branch_and_link_instructions + I1 = NOT(J1 EOR S) + I2 = NOT(J2 EOR S) + imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', S & 0x1, 32) - } + } - @rules { + @hooks { - //chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_blx_from_thumb + link = handle_call_as_link + post = post_process_branch_and_link_instructions - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 1 0 1 1 imm24(24) + @word cond(4) 1 0 1 1 imm24(24) - @syntax <imm32> + @syntax <imm32> - @conv { + @conv { - imm32 = SignExtend(imm24:'00', imm24 & 0x800000, 32) + imm32 = SignExtend(imm24:'00', imm24 & 0x800000, 32) - } + } - @hooks { + @rules { - fetch = help_fetching_with_instruction_bl_from_arm - link = handle_call_as_link - post = post_process_branch_and_link_instructions + chk_call StoreCondition(cond) - } + } - @rules { + @hooks { - //chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_bl_from_arm + link = handle_call_as_link + post = post_process_branch_and_link_instructions - } + } } -@encoding(A2) { +@encoding (A2) { - @word 1 1 1 1 1 0 1 H(1) imm24(24) + @word 1 1 1 1 1 0 1 H(1) imm24(24) - @syntax "blx" <imm32> + @syntax "blx" <imm32> - @conv { + @conv { - imm32 = SignExtend(imm24:H:'0', imm24 & 0x800000, 32) + imm32 = SignExtend(imm24:H:'0', imm24 & 0x800000, 32) - } + } - @hooks { + @hooks { - fetch = help_fetching_with_instruction_blx_from_arm - link = handle_call_as_link - post = post_process_branch_and_link_instructions + fetch = help_fetching_with_instruction_blx_from_arm + link = handle_call_as_link + post = post_process_branch_and_link_instructions - } - - @rules { - - //chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/blx_A8826.d b/src/arch/arm/v7/opdefs/blx_A8826.d index bc26867..29719fa 100644 --- a/src/arch/arm/v7/opdefs/blx_A8826.d +++ b/src/arch/arm/v7/opdefs/blx_A8826.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,46 +23,39 @@ @title BLX (register) -@encoding(t1) { +@desc Branch with Link and Exchange (register) calls a subroutine at an address and instruction set specified by a register. - @half 0 1 0 0 0 1 1 1 1 Rm(4) 0 0 0 +@encoding (t1) { - @syntax <Rm> + @half 0 1 0 0 0 1 1 1 1 Rm(4) 0 0 0 - @conv { + @syntax <reg_M> - Rm = Register(Rm) + @conv { - } + reg_M = Register(Rm) - @rules { - - //if m == 15 then UNPREDICTABLE; - //if InITBlock() && !LastInITBlock() then UNPREDICTABLE; - //chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 Rm(4) + @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 Rm(4) - @syntax {c} <Rm> + @syntax <reg_M> - @conv { + @conv { - c = Condition(cond) - Rm = Register(Rm) + reg_M = Register(Rm) - } + } - @rules { + @rules { - //if m == 15 then UNPREDICTABLE; - //chk_call SetInsFlag(AIF_RETURN_POINT) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/bx_A8827.d b/src/arch/arm/v7/opdefs/bx_A8827.d index 75921ac..f278d85 100644 --- a/src/arch/arm/v7/opdefs/bx_A8827.d +++ b/src/arch/arm/v7/opdefs/bx_A8827.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,56 +23,51 @@ @title BX -@encoding(t1) { +@desc Branch and Exchange causes a branch to an address and instruction set specified by a register. +@encoding (t1) { - @half 0 1 0 0 0 1 1 1 0 Rm(4) 0 0 0 + @half 0 1 0 0 0 1 1 1 0 Rm(4) 0 0 0 - @syntax <Rm> + @syntax <reg_M> - @conv { + @conv { - Rm = Register(Rm) + reg_M = Register(Rm) - } + } - @hooks { + @hooks { - fetch = help_fetching_with_instruction_bx_from_thumb + fetch = help_fetching_with_instruction_bx_from_thumb - } - - @rules { - - chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 Rm(4) + @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 Rm(4) - @syntax {c} <Rm> + @syntax <reg_M> - @conv { + @conv { - c = Condition(cond) - Rm = Register(Rm) + reg_M = Register(Rm) - } + } - @hooks { + @rules { - fetch = help_fetching_with_instruction_bx_from_thumb + chk_call StoreCondition(cond) - } + } - @rules { + @hooks { - chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_bx_from_thumb - } + } } + diff --git a/src/arch/arm/v7/opdefs/bxj_A8828.d b/src/arch/arm/v7/opdefs/bxj_A8828.d new file mode 100644 index 0000000..efa2de2 --- /dev/null +++ b/src/arch/arm/v7/opdefs/bxj_A8828.d @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title BXJ + +@desc Branch and Exchange Jazelle attempts to change to Jazelle state. If the attempt fails, it branches to an address and instruction set specified by a register as though it were a BX instruction. In an implementation that includes the Virtualization Extensions, if HSTR.TJDBX is set to 1, execution of a BXJ instruction in a Non-secure mode other than Hyp mode generates a Hyp Trap exception. For more information see Trapping accesses to Jazelle functionality on page B1-1255. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 1 0 0 Rm(4) 1 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 + + @syntax <reg_M> + + @conv { + + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 Rm(4) + + @syntax <reg_M> + + @conv { + + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/cbnz_A8829.d b/src/arch/arm/v7/opdefs/cb_A8829.d index f5f9602..134e0f4 100644 --- a/src/arch/arm/v7/opdefs/cbnz_A8829.d +++ b/src/arch/arm/v7/opdefs/cb_A8829.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,48 +23,36 @@ @title CBNZ, CBZ -@encoding(t11) { +@desc Compare and Branch on Nonzero and Compare and Branch on Zero compare the value in a register with zero, and conditionally branch forward a constant value. They do not affect the condition flags. - @half 1 0 1 1 1 0 i(1) 1 imm5(5) Rn(3) +@encoding (t1) { - @syntax <Rn> <label> + @half 1 0 1 1 op(1) 0 i(1) 1 imm5(5) Rn(3) - @conv { + @syntax <reg_N> <imm32> - Rn = Register(Rn) - label = ZeroExtend(i:imm5:'0', 7, 32); + @conv { - } + reg_N = Register(Rn) + imm32 = ZeroExtend(i:imm5:'0', 32) + nonzero = (op == '1') - @hooks { + } - fetch = help_fetching_with_instruction_cb_n_z - link = handle_comp_and_branch_if_true_as_link - post = post_process_comp_and_branch_instructions + @rules { - } + if (nonzero); chk_call ExtendKeyword("n") + chk_call ExtendKeyword("z") -} - -@encoding(t12) { - - @half 1 0 1 1 0 0 i(1) 1 imm5(5) Rn(3) - - @syntax "cbz" <Rn> <label> + } - @conv { + @hooks { - Rn = Register(Rn) - label = ZeroExtend(i:imm5:'0', 7, 32); + fetch = help_fetching_with_instruction_cb_n_z + link = handle_comp_and_branch_if_true_as_link + post = post_process_comp_and_branch_instructions - } - - @hooks { - - fetch = help_fetching_with_instruction_cb_n_z - link = handle_comp_and_branch_if_true_as_link - post = post_process_comp_and_branch_instructions - - } + } } + diff --git a/src/arch/arm/v7/opdefs/cdp_A8830.d b/src/arch/arm/v7/opdefs/cdp_A8830.d new file mode 100644 index 0000000..109b89b --- /dev/null +++ b/src/arch/arm/v7/opdefs/cdp_A8830.d @@ -0,0 +1,109 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title CDP, CDP2 + +@desc Coprocessor Data Processing tells a coprocessor to perform an operation that is independent of ARM core registers and memory. If no coprocessor can execute the instruction, an Undefined Instruction exception is generated. This is a generic coprocessor instruction. Some of the fields have no functionality defined by the architecture and are free for use by the coprocessor instruction set designer. These are the opc1, opc2, CRd, CRn, and CRm fields. However, coprocessors CP8-CP15 are reserved for use by ARM, and this manual defines the valid CDP and CDP2 instructions when coproc is in the range p8-p15. For more information see Coprocessor support on page A2-94. + +@encoding (T1) { + + @word 1 1 1 0 1 1 1 0 opc1(4) CRn(4) CRd(4) coproc(4) opc2(3) 0 CRm(4) + + @syntax <cp> <undef_opc1> <creg_D> <creg_N> <creg_M> <undef_opc2> + + @conv { + + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_D = CRegister(CRd) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + +@encoding (A1) { + + @word cond(4) 1 1 1 0 opc1(4) CRn(4) CRd(4) coproc(4) opc2(3) 0 CRm(4) + + @syntax <cp> <undef_opc1> <creg_D> <creg_N> <creg_M> <undef_opc2> + + @conv { + + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_D = CRegister(CRd) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 1 1 0 opc1(4) CRn(4) CRd(4) coproc(4) opc2(3) 0 CRm(4) + + @syntax "cdp2" <cp> <undef_opc1> <creg_D> <creg_N> <creg_M> <undef_opc2> + + @conv { + + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_D = CRegister(CRd) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + +@encoding (A2) { + + @word 1 1 1 1 1 1 1 0 opc1(4) CRn(4) CRd(4) coproc(4) opc2(3) 0 CRm(4) + + @syntax "cdp2" <cp> <undef_opc1> <creg_D> <creg_N> <creg_M> <undef_opc2> + + @conv { + + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_D = CRegister(CRd) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/clrex_A8832.d b/src/arch/arm/v7/opdefs/clrex_A8832.d new file mode 100644 index 0000000..4f313f2 --- /dev/null +++ b/src/arch/arm/v7/opdefs/clrex_A8832.d @@ -0,0 +1,39 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title CLREX + +@desc Clear-Exclusive clears the local record of the executing processor that an address has had a request for an exclusive access. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 0 1 1 1 1 + +} + +@encoding (A1) { + + @word 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 + +} + diff --git a/src/arch/arm/v7/opdefs/clz_A8833.d b/src/arch/arm/v7/opdefs/clz_A8833.d new file mode 100644 index 0000000..d4fdac6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/clz_A8833.d @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title CLZ + +@desc Count Leading Zeros returns the number of binary zero bits before the first binary one bit in a value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 1 Rm(4) 1 1 1 1 Rd(4) 1 0 0 0 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 1 1 0 1 1 1 1 Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/cmn_A8834.d b/src/arch/arm/v7/opdefs/cmn_A8834.d index ff403f3..fc0b19f 100644 --- a/src/arch/arm/v7/opdefs/cmn_A8834.d +++ b/src/arch/arm/v7/opdefs/cmn_A8834.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,39 +23,41 @@ @title CMN (immediate) -@encoding(T1) { +@desc Compare Negative (immediate) adds a register value and an immediate value. It updates the condition flags based on the result, and discards the result. - @word 1 1 1 1 0 i(1) 0 1 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) +@encoding (T1) { - @syntax <Rn> <const> + @word 1 1 1 1 0 i(1) 0 1 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) - @conv { + @syntax <reg_N> <imm32> - Rn = Register(Rn) - const = ThumbExpandImm(i:imm3:imm8) + @conv { - } + reg_N = Register(Rn) + imm32 = ThumbExpandImm(i:imm3:imm8) - @rules { + } - if (Rn == '1111') ; unpredictable +} - } +@encoding (A1) { -} + @word cond(4) 0 0 1 1 0 1 1 1 Rn(4) 0 0 0 0 imm12(12) -@encoding(A1) { + @syntax <reg_N> <imm32> - @word cond(4) 0 0 1 1 0 1 1 1 Rn(4) 0 0 0 0 imm12(12) + @conv { - @syntax {c} <Rn> <const> + reg_N = Register(Rn) + imm32 = ARMExpandImm(imm12) - @conv { + } - c = Condition(cond) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + @rules { - } + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/cmn_A8835.d b/src/arch/arm/v7/opdefs/cmn_A8835.d index e96f17f..cd228de 100644 --- a/src/arch/arm/v7/opdefs/cmn_A8835.d +++ b/src/arch/arm/v7/opdefs/cmn_A8835.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,56 +23,58 @@ @title CMN (register) -@encoding(t1) { +@desc Compare Negative (register) adds a register value and an optionally-shifted register value. It updates the condition flags based on the result, and discards the result. - @half 0 1 0 0 0 0 1 0 1 1 Rm(3) Rn(3) +@encoding (t1) { - @syntax <Rn> <Rm> + @half 0 1 0 0 0 0 1 0 1 1 Rm(3) Rn(3) - @conv { + @syntax <reg_N> <reg_M> - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_N = Register(Rn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 1 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 1 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) - @syntax <Rn> <Rm> <?shift> + @syntax ".W" <reg_N> <reg_M> <?shift> - @conv { + @conv { - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { +} - //if n == 15 || m IN {13,15} then UNPREDICTABLE +@encoding (A1) { - } + @word cond(4) 0 0 0 1 0 1 1 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) -} + @syntax <reg_N> <reg_M> <?shift> -@encoding(A1) { + @conv { - @word cond(4) 0 0 0 1 0 1 1 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm5) - @syntax {c} <Rn> <Rm> <?shift> + } - @conv { + @rules { - c = Condition(cond) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/cmn_A8836.d b/src/arch/arm/v7/opdefs/cmn_A8836.d new file mode 100644 index 0000000..ad58482 --- /dev/null +++ b/src/arch/arm/v7/opdefs/cmn_A8836.d @@ -0,0 +1,49 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title CMN (register-shifted register) + +@desc Compare Negative (register-shifted register) adds a register value and a register-shifted register value. It updates the condition flags based on the result, and discards the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 1 1 1 Rn(4) 0 0 0 0 Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/cmp_A8837.d b/src/arch/arm/v7/opdefs/cmp_A8837.d index bcfe5d2..76b7a76 100644 --- a/src/arch/arm/v7/opdefs/cmp_A8837.d +++ b/src/arch/arm/v7/opdefs/cmp_A8837.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,54 +23,56 @@ @title CMP (immediate) -@encoding(t1) { +@desc Compare (immediate) subtracts an immediate value from a register value. It updates the condition flags based on the result, and discards the result. - @half 0 0 1 0 1 Rn(3) imm8(8) +@encoding (t1) { - @syntax <Rn> <const> + @half 0 0 1 0 1 Rn(3) imm8(8) - @conv { + @syntax <reg_N> <imm32> - Rn = Register(Rn) - const = ZeroExtend(imm8, 8, 32) + @conv { - } + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 i(1) 0 1 1 0 1 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) + @word 1 1 1 1 0 i(1) 0 1 1 0 1 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) - @syntax <Rn> <const> + @syntax ".W" <reg_N> <imm32> - @conv { + @conv { - Rn = Register(Rn) - const = ThumbExpandImm(i:imm3:imm8) + reg_N = Register(Rn) + imm32 = ThumbExpandImm(i:imm3:imm8) - } + } - @rules { +} - if (Rn == '1111') ; unpredictable +@encoding (A1) { - } + @word cond(4) 0 0 1 1 0 1 0 1 Rn(4) 0 0 0 0 imm12(12) -} + @syntax <reg_N> <imm32> -@encoding(A1) { + @conv { - @word cond(4) 0 0 1 1 0 1 0 1 Rn(4) 0 0 0 0 imm12(12) + reg_N = Register(Rn) + imm32 = ARMExpandImm(imm12) - @syntax {c} <Rn> <const> + } - @conv { + @rules { - c = Condition(cond) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/cmp_A8838.d b/src/arch/arm/v7/opdefs/cmp_A8838.d index 7ffe3d9..cd02543 100644 --- a/src/arch/arm/v7/opdefs/cmp_A8838.d +++ b/src/arch/arm/v7/opdefs/cmp_A8838.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,78 +23,73 @@ @title CMP (register) -@encoding(t1) { +@desc Compare (register) subtracts an optionally-shifted register value from a register value. It updates the condition flags based on the result, and discards the result. - @half 0 1 0 0 0 0 1 0 1 0 Rm(3) Rn(3) +@encoding (t1) { - @syntax <Rn> <Rm> + @half 0 1 0 0 0 0 1 0 1 0 Rm(3) Rn(3) - @conv { + @syntax <reg_N> <reg_M> - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_N = Register(Rn) + reg_M = Register(Rm) -} - -@encoding(t2) { + } - @half 0 1 0 0 0 1 0 1 N(1) Rm(4) Rn(3) - - @syntax <Rn> <Rm> +} - @conv { +@encoding (t2) { - Rn = Register(N:Rn) - Rm = Register(Rm) + @half 0 1 0 0 0 1 0 1 N(1) Rm(4) Rn(3) - } + @syntax <reg_N> <reg_M> - @rules { + @conv { - //if n < 8 && m < 8 then UNPREDICTABLE - //if n == 15 || m == 15 then UNPREDICTABLE + reg_N = Register(N:Rn) + reg_M = Register(Rm) - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 0 1 0 1 1 1 0 1 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 1 1 0 1 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) - @syntax <Rn> <Rm> <?shift> + @syntax ".W" <reg_N> <reg_M> <?shift> - @conv { + @conv { - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { +} - //if n == 15 || m IN {13,15} then UNPREDICTABLE +@encoding (A1) { - } + @word cond(4) 0 0 0 1 0 1 0 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) -} + @syntax <reg_N> <reg_M> <?shift> -@encoding(A1) { + @conv { - @word cond(4) 0 0 0 1 0 1 0 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm5) - @syntax {c} <Rn> <Rm> <?shift> + } - @conv { + @rules { - c = Condition(cond) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/cmp_A8839.d b/src/arch/arm/v7/opdefs/cmp_A8839.d new file mode 100644 index 0000000..45ed0f9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/cmp_A8839.d @@ -0,0 +1,49 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title CMP (register-shifted register) + +@desc Compare (register-shifted register) subtracts a register-shifted register value from a register value. It updates the condition flags based on the result, and discards the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 1 0 1 Rn(4) 0 0 0 0 Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/dbg_A8842.d b/src/arch/arm/v7/opdefs/dbg_A8842.d new file mode 100644 index 0000000..62142f5 --- /dev/null +++ b/src/arch/arm/v7/opdefs/dbg_A8842.d @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title DBG + +@desc Debug Hint provides a hint to debug and related systems. See their documentation for what use (if any) they make of this instruction. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 option(4) + + @syntax <undef_option> + + @conv { + + undef_option = RawValue(option) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 option(4) + + @syntax <undef_option> + + @conv { + + undef_option = RawValue(option) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/dmb_A8843.d b/src/arch/arm/v7/opdefs/dmb_A8843.d new file mode 100644 index 0000000..34f053a --- /dev/null +++ b/src/arch/arm/v7/opdefs/dmb_A8843.d @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title DMB + +@desc Data Memory Barrier is a memory barrier that ensures the ordering of observations of memory accesses, see Data Memory Barrier (DMB) on page A3-151. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 0 1 0 1 option(4) + + @syntax <limitation> + + @conv { + + limitation = BarrierLimitation(option) + + } + +} + +@encoding (A1) { + + @word 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 0 1 option(4) + + @syntax <limitation> + + @conv { + + limitation = BarrierLimitation(option) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/dsb_A8844.d b/src/arch/arm/v7/opdefs/dsb_A8844.d new file mode 100644 index 0000000..512220c --- /dev/null +++ b/src/arch/arm/v7/opdefs/dsb_A8844.d @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title DSB + +@desc Data Synchronization Barrier is a memory barrier that ensures the completion of memory accesses, see Data Synchronization Barrier (DSB) on page A3-152. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 0 1 0 0 option(4) + + @syntax <limitation> + + @conv { + + limitation = BarrierLimitation(option) + + } + +} + +@encoding (A1) { + + @word 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 0 0 option(4) + + @syntax <limitation> + + @conv { + + limitation = BarrierLimitation(option) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/eor_A8846.d b/src/arch/arm/v7/opdefs/eor_A8846.d index 2c71098..38dc858 100644 --- a/src/arch/arm/v7/opdefs/eor_A8846.d +++ b/src/arch/arm/v7/opdefs/eor_A8846.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,50 +23,52 @@ @title EOR (immediate) -@encoding(T1) { +@desc Bitwise Exclusive OR (immediate) performs a bitwise Exclusive OR of a register value and an immediate value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word 1 1 1 1 0 i(1) 0 0 1 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <const> + @word 1 1 1 1 0 i(1) 0 0 1 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - //if ((Rd == '1111') && (S == '1')) ; see TST (immediate) - //if ((d == 13) || ((d == 15) && (S == '0')) || (n IN {13,15})) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 0 0 1 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 0 0 0 1 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm_C(imm12, 0) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm_C(imm12, 0) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/eor_A8847.d b/src/arch/arm/v7/opdefs/eor_A8847.d index 3d7f5b5..66643a1 100644 --- a/src/arch/arm/v7/opdefs/eor_A8847.d +++ b/src/arch/arm/v7/opdefs/eor_A8847.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,67 +23,70 @@ @title EOR (register) -@encoding(t1) { +@desc Bitwise Exclusive OR (register) performs a bitwise Exclusive OR of a register value and an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 0 0 0 1 Rm(3) Rdn(3) +@encoding (t1) { - @syntax <Rdn> <Rm> + @half 0 1 0 0 0 0 0 0 0 1 Rm(3) Rdn(3) - @conv { + @syntax "eors" <reg_DN> <reg_M> - Rdn = Register(Rdn) - Rm = Register(Rm) + @conv { - } + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 1 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 0 1 0 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see TEQ (register) - //if ((d == 13) || ((d == 15) && (S == '0')) || (n IN {13,15})) ; unpredictable + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 0 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 0 0 0 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/eor_A8848.d b/src/arch/arm/v7/opdefs/eor_A8848.d new file mode 100644 index 0000000..f38fa74 --- /dev/null +++ b/src/arch/arm/v7/opdefs/eor_A8848.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title EOR (register-shifted register) + +@desc Bitwise Exclusive OR (register-shifted register) performs a bitwise Exclusive OR of a register value and a register-shifted register value. It writes the result to the destination register, and can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 0 0 1 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldr_A8862.d b/src/arch/arm/v7/opdefs/ldr_A8862.d index e2f9e3f..03df506 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8862.d +++ b/src/arch/arm/v7/opdefs/ldr_A8862.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,118 +23,76 @@ @title LDR (immediate, Thumb) -@encoding(t1) { +@desc Load Register (immediate) calculates an address from a base register value and an immediate offset, loads a word from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 1 0 1 imm5(5) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt> <access> + @half 0 1 1 0 1 imm5(5) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm5:'00', 7, 32); - access = MakeMemoryAccess(Rgn, imm32, 1, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm5:'00', 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) -} - -@encoding(t2) { - - @half 1 0 0 1 1 Rt(3) imm8(8) - - @syntax <Rgt> <access> - - @conv { - - Rgt = Register(Rt) - Sp = Register(13) - imm32 = ZeroExtend(imm8:'00', 10, 32); - access = MakeMemoryAccess(Sp, imm32, 1, 0) - - } + } } -@encoding(T3) { - - @word 1 1 1 1 1 0 0 0 1 1 0 1 Rn(4) Rt(4) imm12(12) - - @syntax "ldr.W" <Rgt> <access> +@encoding (t2) { - @conv { + @half 1 0 0 1 1 Rt(3) imm8(8) - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - access = MakeMemoryAccess(Rgn, imm32, 1, 0) + @syntax <reg_T> <mem_access> - } + @conv { - @rules { + reg_T = Register(Rt) + imm32 = ZeroExtend(imm8:'00', 32) + SP = Register(13) + mem_access = MakeMemoryAccess(SP, imm32, NULL, true, true, false) - //if Rn == '1111' then SEE LDR (literal); - //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(T41) { - - @word 1 1 1 1 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 1 1 U(1) W(1) imm8(8) - - @syntax <Rgt> <access> - - @conv { +@encoding (T3) { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - access = MakeMemoryAccess(Rgn, imm32, U, W) + @word 1 1 1 1 1 0 0 0 1 1 0 1 Rn(4) Rt(4) imm12(12) - } + @syntax ".W" <reg_T> <mem_access> - @rules { + @conv { - //if Rn == '1111' then SEE LDR (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRT; - //if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; - //if P == '0' && W == '0' then UNDEFINED; - //if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) - } + } } -@encoding(T42) { +@encoding (T4) { - @word 1 1 1 1 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 1 0 U(1) W(1) imm8(8) + @word 1 1 1 1 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) - @syntax <Rgt> <base> <offset> + @syntax <reg_T> <mem_access> - @conv { + @conv { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - } - - @rules { - - //if Rn == '1111' then SEE LDR (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRT; - //if Rn == '1101' && P == '0' && U == '1' && W == '1' && imm8 == '00000100' then SEE POP; - //if P == '0' && W == '0' then UNDEFINED; - //if (wback && n == t) || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/ldr_A8863.d b/src/arch/arm/v7/opdefs/ldr_A8863.d index b2f7f84..0d0ce1f 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8863.d +++ b/src/arch/arm/v7/opdefs/ldr_A8863.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,61 +23,31 @@ @title LDR (immediate, ARM) -@encoding(A11) { +@desc Load Register (immediate) calculates an address from a base register value and an immediate offset, loads a word from memory, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @word cond(4) 0 1 0 1 U(1) 0 W(1) 1 Rn(4) Rt(4) imm12(12) +@encoding (A1) { - @syntax <Rgt> <access> + @word cond(4) 0 1 0 P(1) U(1) 0 W(1) 1 Rn(4) Rt(4) imm12(12) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - access = MakeMemoryAccess(Rgn, imm32, U, 1) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - @rules { + } - //if Rn == '1111' then SEE LDR (literal); - //if P == '0' && W == '1' then SEE LDRT; - //if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; - //t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - //if wback && n == t then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + @rules { - } + chk_call StoreCondition(cond) -} - -@encoding(A12) { - - @word cond(4) 0 1 0 0 U(1) 0 W(1) 1 Rn(4) Rt(4) imm12(12) - - @syntax <Rgt> <base> <offset> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) - - } - - @rules { - - //if Rn == '1111' then SEE LDR (literal); - //if P == '0' && W == '1' then SEE LDRT; - //if Rn == '1101' && P == '0' && U == '1' && W == '0' && imm12 == '000000000100' then SEE POP; - //t = UInt(Rt); n = UInt(Rn); imm32 = ZeroExtend(imm12, 32); - //index = (P == '1'); add = (U == '1'); wback = (P == '0') || (W == '1'); - //if wback && n == t then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/ldr_A8864.d b/src/arch/arm/v7/opdefs/ldr_A8864.d index bd7ed50..74afa2d 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8864.d +++ b/src/arch/arm/v7/opdefs/ldr_A8864.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,86 +23,77 @@ @title LDR (literal) -@encoding(t1) { +@desc Load Register (literal) calculates an address from the PC value and an immediate offset, loads a word from memory, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 0 0 1 Rt(3) imm8(8) +@encoding (t1) { - @syntax <Rgt> <label> + @half 0 1 0 0 1 Rt(3) imm8(8) - @conv { + @syntax <reg_T> <imm32> - Rgt = Register(Rt) - imm32 = ZeroExtend(imm8:'00', 10, 32) - label = MakeAccessOffset(1, imm32) + @conv { - } + reg_T = Register(Rt) + imm32 = ZeroExtend(imm8:'00', 32) - @hooks { + } - fetch = help_fetching_with_instruction_ldr_literal_from_thumb - post = post_process_ldr_instructions + @hooks { - } + fetch = help_fetching_with_instruction_ldr_literal_from_thumb + post = post_process_ldr_instructions -} - -@encoding(T2) { - - @word 1 1 1 1 1 0 0 0 U(1) 1 0 1 1 1 1 1 Rt(4) imm12(12) + } - @syntax <Rgt> <label> +} - @conv { +@encoding (T2) { - Rgt = Register(Rt) - imm32 = ZeroExtend(imm12, 12, 32) - label = MakeAccessOffset(U, imm32) + @word 1 1 1 1 1 0 0 0 U(1) 1 0 1 1 1 1 1 Rt(4) imm12(12) - } + @syntax ".W" <reg_T> <imm32> - @hooks { + @conv { - fetch = help_fetching_with_instruction_ldr_literal_from_thumb - post = post_process_ldr_instructions + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) - } + } - @rules { + @hooks { - //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_ldr_literal_from_thumb + post = post_process_ldr_instructions - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 1 0 1 U(1) 0 0 1 1 1 1 1 Rt(4) imm12(12) + @word cond(4) 0 1 0 1 U(1) 0 0 1 1 1 1 1 Rt(4) imm12(12) - @syntax {c} <Rgt> <label> + @syntax <reg_T> <imm32> - @conv { + @conv { - c = Condition(cond) - Rgt = Register(Rt) - imm32 = ZeroExtend(imm12, 12, 32) - label = MakeAccessOffset(U, imm32) + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) - } + } - @hooks { + @rules { - fetch = help_fetching_with_instruction_ldr_literal_from_arm - post = post_process_ldr_instructions + chk_call StoreCondition(cond) - } + } - @rules { + @hooks { - //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + fetch = help_fetching_with_instruction_ldr_literal_from_arm + post = post_process_ldr_instructions - } + } } + diff --git a/src/arch/arm/v7/opdefs/ldr_A8865.d b/src/arch/arm/v7/opdefs/ldr_A8865.d index b6a0126..ebb4e09 100644 --- a/src/arch/arm/v7/opdefs/ldr_A8865.d +++ b/src/arch/arm/v7/opdefs/ldr_A8865.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,52 +23,40 @@ @title LDR (register, Thumb) -@encoding(t1) { +@desc Load Register (register) calculates an address from a base register value and an offset register value, loads a word from memory, and writes it to a register. The offset register value can optionally be shifted. For information about memory accesses, see Memory accesses on page A8-294. The Thumb form of LDR (register) does not support register writeback. - @half 0 1 0 1 1 0 0 Rm(3) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt> <access> + @half 0 1 0 1 1 0 0 Rm(3) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - access = _MakeMemoryAccess(Rgn, Rgm, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, false, false) - @rules { - - //if CurrentInstrSet() == InstrSet_ThumbEE then SEE "Modified operation in ThumbEE"; - - } + } } -@encoding(T2) { - - @word 1 1 1 1 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) +@encoding (T2) { - @syntax "ldr.W" <Rgt>, <access> + @word 1 1 1 1 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) - @conv { + @syntax ".W" <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - shift = DecodeImmShift(0, imm2) - access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, false, false) - @rules { - - //if Rn == '1111' then SEE LDR (literal); - //if m IN {13,15} then UNPREDICTABLE; - //if t == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/ldr_A8866.d b/src/arch/arm/v7/opdefs/ldr_A8866.d new file mode 100644 index 0000000..b161043 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldr_A8866.d @@ -0,0 +1,54 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDR (register, ARM) + +@desc Load Register (register) calculates an address from a base register value and an offset register value, loads a word from memory, and writes it to a register. The offset register value can optionally be shifted. For information about memory accesses, see Memory accesses on page A8-294. + +@encoding (A1) { + + @word cond(4) 0 1 1 P(1) U(1) 0 W(1) 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + shift = DecodeImmShift(type, imm5) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrb_A8867.d b/src/arch/arm/v7/opdefs/ldrb_A8867.d index c772b08..2dea64e 100644 --- a/src/arch/arm/v7/opdefs/ldrb_A8867.d +++ b/src/arch/arm/v7/opdefs/ldrb_A8867.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,102 +23,59 @@ @title LDRB (immediate, Thumb) -@encoding(t1) { +@desc Load Register Byte (immediate) calculates an address from a base register value and an immediate offset, loads a byte from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 1 1 1 imm5(5) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt>, <access> + @half 0 1 1 1 1 imm5(5) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm5, 5, 32) - access = MakeMemoryAccess(Rgn, imm32, 1, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm5, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) -} - -@encoding(T2) { - - @word 1 1 1 1 1 0 0 0 1 0 0 1 Rn(4) Rt(4) imm12(12) - - @syntax "ldrb.W" <Rgt>, <access> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32) - access = MakeMemoryAccess(Rgn, imm32, 1, 0) - - } - - @rules { - - //if Rt == '1111' then SEE PLD; - //if Rn == '1111' then SEE LDRB (literal); - //if t == 13 then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(T31) { - - @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 1 1 U(1) W(1) imm8(8) - - @syntax <Rgt> <access> - - @conv { +@encoding (T2) { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - access = MakeMemoryAccess(Rgn, imm32, U, W) + @word 1 1 1 1 1 0 0 0 1 0 0 1 Rn(4) Rt(4) imm12(12) - } + @syntax ".W" <reg_T> <mem_access> - @rules { + @conv { - //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); - //if Rn == '1111' then SEE LDRB (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRBT; - //if P == '0' && W == '0' then UNDEFINED; - //if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) - } + } } -@encoding(T32) { +@encoding (T3) { - @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 1 0 U(1) W(1) imm8(8) + @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) - @syntax <Rgt> <base> <offset> + @syntax <reg_T> <mem_access> - @conv { + @conv { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - } - - @rules { - - //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); - //if Rn == '1111' then SEE LDRB (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRBT; - //if P == '0' && W == '0' then UNDEFINED; - //if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/ldrb_A8868.d b/src/arch/arm/v7/opdefs/ldrb_A8868.d index 579db06..519c309 100644 --- a/src/arch/arm/v7/opdefs/ldrb_A8868.d +++ b/src/arch/arm/v7/opdefs/ldrb_A8868.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,59 +23,31 @@ @title LDRB (immediate, ARM) -@encoding(A11) { +@desc Load Register Byte (immediate) calculates an address from a base register value and an immediate offset, loads a byte from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @word cond(4) 0 1 0 1 U(1) 1 W(1) 1 Rn(4) Rt(4) imm12(12) +@encoding (A1) { - @syntax <Rgt> <access> + @word cond(4) 0 1 0 P(1) U(1) 1 W(1) 1 Rn(4) Rt(4) imm12(12) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - access = MakeMemoryAccess(Rgn, imm32, U, W) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - @rules { + } - //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); - //if Rn == '1111' then SEE LDRB (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRBT; - //if P == '0' && W == '0' then UNDEFINED; - //if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + @rules { - } + chk_call StoreCondition(cond) -} - -@encoding(A12) { - - @word cond(4) 0 1 0 0 U(1) 1 W(1) 1 Rn(4) Rt(4) imm12(12) - - @syntax <Rgt> <base> <offset> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) - - } - - @rules { - - //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); - //if Rn == '1111' then SEE LDRB (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRBT; - //if P == '0' && W == '0' then UNDEFINED; - //if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/ldrb_A8869.d b/src/arch/arm/v7/opdefs/ldrb_A8869.d new file mode 100644 index 0000000..fb80049 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrb_A8869.d @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRB (literal) + +@desc Load Register Byte (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, zero-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 0 U(1) 0 0 1 1 1 1 1 Rt(4) imm12(12) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 0 1 U(1) 1 0 1 1 1 1 1 Rt(4) imm12(12) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrb_A8870.d b/src/arch/arm/v7/opdefs/ldrb_A8870.d index 2b6f2e9..35f95ab 100644 --- a/src/arch/arm/v7/opdefs/ldrb_A8870.d +++ b/src/arch/arm/v7/opdefs/ldrb_A8870.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,107 +23,67 @@ @title LDRB (register) -@encoding(t1) { +@desc Load Register Byte (register) calculates an address from a base register value and an offset register value, loads a byte from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can optionally be shifted. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 0 1 1 1 0 Rm(3) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt> <access> + @half 0 1 0 1 1 1 0 Rm(3) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - access = _MakeMemoryAccess(Rgn, Rgm, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, true, false) - @rules { - - } + } } -@encoding(T2) { - - @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) - - @syntax "ldrb.W" <Rgt>, <access> - - @conv { +@encoding (T2) { - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - shift = DecodeImmShift(0, imm2) - access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, 0) + @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) - } + @syntax ".W" <reg_T> <mem_access> - @rules { + @conv { - //if Rn == '1111' then UNDEFINED; - //if t IN {13,15} || m IN {13,15} then UNPREDICTABLE; + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, true, false) - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(A11) { +@encoding (A1) { - @word cond(4) 0 1 1 1 U(1) 1 W(1) 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 1 1 P(1) U(1) 1 W(1) 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) - @syntax <Rgt> <access> + @syntax <reg_T> <mem_access> - @conv { + @conv { - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - shift = DecodeImmShift(type, imm5) - access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, W) + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + shift = DecodeImmShift(type, imm5) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, index, add, wback) - } + } - @rules { + @rules { - //if P == '0' && W == '1' then SEE LDRBT; - //if t == 15 || m == 15 then UNPREDICTABLE; - //if wback && (n == 15 || n == t) then UNPREDICTABLE; - //if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + chk_call StoreCondition(cond) - } + } } -@encoding(A12) { - - @word cond(4) 0 1 1 0 U(1) 1 W(1) 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) - - @syntax <Rgt> <base> <offset> <?shift> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - base = MakeMemoryNotIndexed(Rgn, 1) - offset = MakeAccessOffset(U, Rgm) - shift = DecodeImmShift(type, imm5) - - } - - @rules { - - //if P == '0' && W == '1' then SEE LDRBT; - //if t == 15 || m == 15 then UNPREDICTABLE; - //if wback && (n == 15 || n == t) then UNPREDICTABLE; - //if ArchVersion() < 6 && wback && m == n then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } - -} diff --git a/src/arch/arm/v7/opdefs/ldrbt_A8871.d b/src/arch/arm/v7/opdefs/ldrbt_A8871.d new file mode 100644 index 0000000..0bf9c3c --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrbt_A8871.d @@ -0,0 +1,93 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRBT + +@desc Load Register Byte Unprivileged loads a byte from memory, zero-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. The memory access is restricted as if the processor were running in User mode. This makes no difference if the processor is actually running in User mode. LDRBT is UNPREDICTABLE in Hyp mode. The Thumb instruction uses an offset addressing mode, that calculates the address used for the memory access from a base register value and an immediate offset, and leaves the base register unchanged. The ARM instruction uses a post-indexed addressing mode, that uses a base register value as the address for the memory access, and calculates a new address from a base register value and an offset and writes it back to the base register. The offset can be an immediate value or an optionally-shifted register value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 0 0 0 0 1 Rn(4) Rt(4) 1 1 1 0 imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 0 0 U(1) 1 1 1 Rn(4) Rt(4) imm12(12) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + add = (U == '1') + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (A2) { + + @word cond(4) 0 1 1 0 U(1) 1 1 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + add = (U == '1') + shift = DecodeImmShift(type, imm5) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrd_A8872.d b/src/arch/arm/v7/opdefs/ldrd_A8872.d new file mode 100644 index 0000000..c73fdca --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrd_A8872.d @@ -0,0 +1,75 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRD (immediate) + +@desc Load Register Dual (immediate) calculates an address from a base register value and an immediate offset, loads two words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 0 1 0 0 P(1) U(1) 1 W(1) 1 Rn(4) Rt(4) Rt2(4) imm8(8) + + @syntax <reg_T> <reg_T2> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8:'00', 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 1 W(1) 0 Rn(4) Rt(4) imm4H(4) 1 1 0 1 imm4L(4) + + @syntax <reg_T> <reg_T2> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_T2 = NextRegister(reg_T) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm4H:imm4L, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrd_A8873.d b/src/arch/arm/v7/opdefs/ldrd_A8873.d new file mode 100644 index 0000000..828e4a3 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrd_A8873.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRD (literal) + +@desc Load Register Dual (literal) calculates an address from the PC value and an immediate offset, loads two words from memory, and writes them to two registers. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 0 1 0 0 P(1) U(1) 1 W(1) 1 1 1 1 1 Rt(4) Rt2(4) imm8(8) + + @syntax <reg_T> <reg_T2> <imm32> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + imm32 = ZeroExtend(imm8:'00', 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 U(1) 1 0 0 1 1 1 1 Rt(4) imm4H(4) 1 1 0 1 imm4L(4) + + @syntax <reg_T> <reg_T2> <imm32> + + @conv { + + reg_T = Register(Rt) + reg_T2 = NextRegister(reg_T) + imm32 = ZeroExtend(imm4H:imm4L, 32) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrd_A8874.d b/src/arch/arm/v7/opdefs/ldrd_A8874.d new file mode 100644 index 0000000..ed055a6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrd_A8874.d @@ -0,0 +1,54 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRD (register) + +@desc Load Register Dual (register) calculates an address from a base register value and a register offset, loads two words from memory, and writes them to two registers. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 0 W(1) 0 Rn(4) Rt(4) 0 0 0 0 1 1 0 1 Rm(4) + + @syntax <reg_T> <reg_T2> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_T2 = NextRegister(reg_T) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrex_A8875.d b/src/arch/arm/v7/opdefs/ldrex_A8875.d new file mode 100644 index 0000000..b915061 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrex_A8875.d @@ -0,0 +1,66 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDREX + +@desc Load Register Exclusive calculates an address from a base register value and an immediate offset, loads a word from memory, writes it to a register and: • if the address has the Shared Memory attribute, marks the physical address as exclusive access for the executing processor in a global monitor • causes the executing processor to indicate an active exclusive access in the local monitor. For more information about support for shared memory see Synchronization and semaphores on page A3-114. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 0 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 1 1 1 1 imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8:'00', 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, false, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 0 1 Rn(4) Rt(4) 1 1 1 1 1 0 0 1 1 1 1 1 + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrexb_A8876.d b/src/arch/arm/v7/opdefs/ldrexb_A8876.d new file mode 100644 index 0000000..e398ef2 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrexb_A8876.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDREXB + +@desc Load Register Exclusive Byte derives an address from a base register value, loads a byte from memory, zero-extends it to form a 32-bit word, writes it to a register and: • if the address has the Shared Memory attribute, marks the physical address as exclusive access for the executing processor in a global monitor • causes the executing processor to indicate an active exclusive access in the local monitor. For more information about support for shared memory see Synchronization and semaphores on page A3-114. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 0 1 0 0 0 1 1 0 1 Rn(4) Rt(4) 1 1 1 1 0 1 0 0 1 1 1 1 + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 1 0 1 Rn(4) Rt(4) 1 1 1 1 1 0 0 1 1 1 1 1 + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrexd_A8877.d b/src/arch/arm/v7/opdefs/ldrexd_A8877.d new file mode 100644 index 0000000..0188cb7 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrexd_A8877.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDREXD + +@desc Load Register Exclusive Doubleword derives an address from a base register value, loads a 64-bit doubleword from memory, writes it to two registers and: • if the address has the Shared Memory attribute, marks the physical address as exclusive access for the executing processor in a global monitor • causes the executing processor to indicate an active exclusive access in the local monitor. For more information about support for shared memory see Synchronization and semaphores on page A3-114. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 0 1 0 0 0 1 1 0 1 Rn(4) Rt(4) Rt2(4) 0 1 1 1 1 1 1 1 + + @syntax <reg_T> <reg_T2> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 1 Rn(4) Rt(4) 1 1 1 1 1 0 0 1 1 1 1 1 + + @syntax <reg_T> <reg_T2> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_T2 = NextRegister(reg_T) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrexh_A8878.d b/src/arch/arm/v7/opdefs/ldrexh_A8878.d new file mode 100644 index 0000000..8e9366f --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrexh_A8878.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDREXH + +@desc Load Register Exclusive Halfword derives an address from a base register value, loads a halfword from memory, zero-extends it to form a 32-bit word, writes it to a register and: • if the address has the Shared Memory attribute, marks the physical address as exclusive access for the executing processor in a global monitor • causes the executing processor to indicate an active exclusive access in the local monitor. For more information about support for shared memory see Synchronization and semaphores on page A3-114. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 0 1 0 0 0 1 1 0 1 Rn(4) Rt(4) 1 1 1 1 0 1 0 1 1 1 1 1 + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 1 1 1 Rn(4) Rt(4) 1 1 1 1 1 0 0 1 1 1 1 1 + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrh_A8879.d b/src/arch/arm/v7/opdefs/ldrh_A8879.d new file mode 100644 index 0000000..3b57bf8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrh_A8879.d @@ -0,0 +1,81 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRH (immediate, Thumb) + +@desc Load Register Halfword (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (t1) { + + @half 1 0 0 0 1 imm5(5) Rn(3) Rt(3) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm5:'0', 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 0 1 0 1 1 Rn(4) Rt(4) imm12(12) + + @syntax ".W" <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (T3) { + + @word 1 1 1 1 1 0 0 0 0 0 1 1 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrh_A8880.d b/src/arch/arm/v7/opdefs/ldrh_A8880.d new file mode 100644 index 0000000..f5f7ab0 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrh_A8880.d @@ -0,0 +1,53 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRH (immediate, ARM) + +@desc Load Register Halfword (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 1 W(1) 1 Rn(4) Rt(4) imm4H(4) 1 0 1 1 imm4L(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm4H:imm4L, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrh_A8881.d b/src/arch/arm/v7/opdefs/ldrh_A8881.d new file mode 100644 index 0000000..59005e4 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrh_A8881.d @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRH (literal) + +@desc Load Register Halfword (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 0 U(1) 0 1 1 1 1 1 1 Rt(4) imm12(12) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 1 W(1) 1 1 1 1 1 Rt(4) imm4H(4) 1 0 1 1 imm4L(4) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm4H:imm4L, 32) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrh_A8882.d b/src/arch/arm/v7/opdefs/ldrh_A8882.d new file mode 100644 index 0000000..823bf24 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrh_A8882.d @@ -0,0 +1,88 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRH (register) + +@desc Load Register Halfword (register) calculates an address from a base register value and an offset register value, loads a halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. The offset register value can be shifted left by 0, 1, 2, or 3 bits. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (t1) { + + @half 0 1 0 1 1 0 1 Rm(3) Rn(3) Rt(3) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 0 0 0 1 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) + + @syntax ".W" <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 0 W(1) 1 Rn(4) Rt(4) 0 0 0 0 1 0 1 1 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrht_A8883.d b/src/arch/arm/v7/opdefs/ldrht_A8883.d new file mode 100644 index 0000000..8f8f015 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrht_A8883.d @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRHT + +@desc Load Register Halfword Unprivileged loads a halfword from memory, zero-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. The memory access is restricted as if the processor were running in User mode. This makes no difference if the processor is actually running in User mode. LDRHT is UNPREDICTABLE in Hyp mode. The Thumb instruction uses an offset addressing mode, that calculates the address used for the memory access from a base register value and an immediate offset, and leaves the base register unchanged. The ARM instruction uses a post-indexed addressing mode, that uses a base register value as the address for the memory access, and calculates a new address from a base register value and an offset and writes it back to the base register. The offset can be an immediate value or a register value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 0 0 0 1 1 Rn(4) Rt(4) 1 1 1 0 imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 0 U(1) 1 1 1 Rn(4) Rt(4) imm4H(4) 1 0 1 1 imm4L(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + add = (U == '1') + imm32 = ZeroExtend(imm4H:imm4L, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (A2) { + + @word cond(4) 0 0 0 0 U(1) 0 1 1 Rn(4) Rt(4) 0 0 0 0 1 0 1 1 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + add = (U == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsb_A8884.d b/src/arch/arm/v7/opdefs/ldrsb_A8884.d new file mode 100644 index 0000000..fc41134 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsb_A8884.d @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSB (immediate) + +@desc Load Register Signed Byte (immediate) calculates an address from a base register value and an immediate offset, loads a byte from memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 1 1 0 0 1 Rn(4) Rt(4) imm12(12) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 1 0 0 0 1 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 1 W(1) 1 Rn(4) Rt(4) imm4H(4) 1 1 0 1 imm4L(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm4H:imm4L, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsb_A8885.d b/src/arch/arm/v7/opdefs/ldrsb_A8885.d new file mode 100644 index 0000000..6cb1d34 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsb_A8885.d @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSB (literal) + +@desc Load Register Signed Byte (literal) calculates an address from the PC value and an immediate offset, loads a byte from memory, sign-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 1 U(1) 0 0 1 1 1 1 1 Rt(4) imm12(12) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 U(1) 1 0 1 1 1 1 1 Rt(4) imm4H(4) 1 1 0 1 imm4L(4) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm4H:imm4L, 32) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsb_A8886.d b/src/arch/arm/v7/opdefs/ldrsb_A8886.d new file mode 100644 index 0000000..4a66278 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsb_A8886.d @@ -0,0 +1,88 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSB (register) + +@desc Load Register Signed Byte (register) calculates an address from a base register value and an offset register value, loads a byte from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be shifted left by 0, 1, 2, or 3 bits. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (t1) { + + @half 0 1 0 1 0 1 1 Rm(3) Rn(3) Rt(3) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 1 0 0 0 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) + + @syntax ".W" <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 0 W(1) 1 Rn(4) Rt(4) 0 0 0 0 1 1 0 1 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsbt_A8887.d b/src/arch/arm/v7/opdefs/ldrsbt_A8887.d new file mode 100644 index 0000000..b545f32 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsbt_A8887.d @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSBT + +@desc Load Register Signed Byte Unprivileged loads a byte from memory, sign-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. The memory access is restricted as if the processor were running in User mode. This makes no difference if the processor is actually running in User mode. LDRSBT is UNPREDICTABLE in Hyp mode. The Thumb instruction uses an offset addressing mode, that calculates the address used for the memory access from a base register value and an immediate offset, and leaves the base register unchanged. The ARM instruction uses a post-indexed addressing mode, that uses a base register value as the address for the memory access, and calculates a new address from a base register value and an offset and writes it back to the base register. The offset can be an immediate value or a register value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 1 0 0 0 1 Rn(4) Rt(4) 1 1 1 0 imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 0 U(1) 1 1 1 Rn(4) Rt(4) imm4H(4) 1 1 0 1 imm4L(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + add = (U == '1') + imm32 = ZeroExtend(imm4H:imm4L, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (A2) { + + @word cond(4) 0 0 0 0 U(1) 0 1 1 Rn(4) Rt(4) 0 0 0 0 1 1 0 1 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + add = (U == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsh_A8888.d b/src/arch/arm/v7/opdefs/ldrsh_A8888.d new file mode 100644 index 0000000..f01024c --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsh_A8888.d @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSH (immediate) + +@desc Load Register Signed Halfword (immediate) calculates an address from a base register value and an immediate offset, loads a halfword from memory, sign-extends it to form a 32-bit word, and writes it to a register. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 1 1 0 1 1 Rn(4) Rt(4) imm12(12) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 1 0 0 1 1 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 1 W(1) 1 Rn(4) Rt(4) imm4H(4) 1 1 1 1 imm4L(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm4H:imm4L, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsh_A8889.d b/src/arch/arm/v7/opdefs/ldrsh_A8889.d new file mode 100644 index 0000000..074cd5c --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsh_A8889.d @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSH (literal) + +@desc Load Register Signed Halfword (literal) calculates an address from the PC value and an immediate offset, loads a halfword from memory, sign-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 1 U(1) 0 1 1 1 1 1 1 Rt(4) imm12(12) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm12, 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 U(1) 1 0 1 1 1 1 1 Rt(4) imm4H(4) 1 1 1 1 imm4L(4) + + @syntax <reg_T> <imm32> + + @conv { + + reg_T = Register(Rt) + imm32 = ZeroExtend(imm4H:imm4L, 32) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsh_A8890.d b/src/arch/arm/v7/opdefs/ldrsh_A8890.d new file mode 100644 index 0000000..eac6c09 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsh_A8890.d @@ -0,0 +1,88 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSH (register) + +@desc Load Register Signed Halfword (register) calculates an address from a base register value and an offset register value, loads a halfword from memory, sign-extends it to form a 32-bit word, and writes it to a register. The offset register value can be shifted left by 0, 1, 2, or 3 bits. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (t1) { + + @half 0 1 0 1 1 1 1 Rm(3) Rn(3) Rt(3) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 1 0 0 1 1 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) + + @syntax ".W" <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 P(1) U(1) 0 W(1) 1 Rn(4) Rt(4) 0 0 0 0 1 1 1 1 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrsht_A8891.d b/src/arch/arm/v7/opdefs/ldrsht_A8891.d new file mode 100644 index 0000000..355178b --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrsht_A8891.d @@ -0,0 +1,92 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRSHT + +@desc Load Register Signed Halfword Unprivileged loads a halfword from memory, sign-extends it to form a 32-bit word, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. The memory access is restricted as if the processor were running in User mode. This makes no difference if the processor is actually running in User mode. LDRSHT is UNPREDICTABLE in Hyp mode. The Thumb instruction uses an offset addressing mode, that calculates the address used for the memory access from a base register value and an immediate offset, and leaves the base register unchanged. The ARM instruction uses a post-indexed addressing mode, that uses a base register value as the address for the memory access, and calculates a new address from a base register value and an offset and writes it back to the base register. The offset can be an immediate value or a register value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 1 0 0 1 1 Rn(4) Rt(4) 1 1 1 0 imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 0 U(1) 1 1 1 Rn(4) Rt(4) imm4H(4) 1 1 1 1 imm4L(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + add = (U == '1') + imm32 = ZeroExtend(imm4H:imm4L, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (A2) { + + @word cond(4) 0 0 0 0 U(1) 0 1 1 Rn(4) Rt(4) 0 0 0 0 1 1 1 1 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + add = (U == '1') + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ldrt_A8892.d b/src/arch/arm/v7/opdefs/ldrt_A8892.d new file mode 100644 index 0000000..e13f0e7 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ldrt_A8892.d @@ -0,0 +1,93 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LDRT + +@desc Load Register Unprivileged loads a word from memory, and writes it to a register. For information about memory accesses see Memory accesses on page A8-294. The memory access is restricted as if the processor were running in User mode. This makes no difference if the processor is actually running in User mode. LDRT is UNPREDICTABLE in Hyp mode. The Thumb instruction uses an offset addressing mode, that calculates the address used for the memory access from a base register value and an immediate offset, and leaves the base register unchanged. The ARM instruction uses a post-indexed addressing mode, that uses a base register value as the address for the memory access, and calculates a new address from a base register value and an offset and writes it back to the base register. The offset can be an immediate value or an optionally-shifted register value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 0 0 0 1 0 1 Rn(4) Rt(4) 1 1 1 0 imm8(8) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 0 0 U(1) 0 1 1 Rn(4) Rt(4) imm12(12) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + add = (U == '1') + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (A2) { + + @word cond(4) 0 1 1 0 U(1) 0 1 1 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + add = (U == '1') + shift = DecodeImmShift(type, imm5) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, false, add, false) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/lsl_A8894.d b/src/arch/arm/v7/opdefs/lsl_A8894.d index 59ac3e8..89924c6 100644 --- a/src/arch/arm/v7/opdefs/lsl_A8894.d +++ b/src/arch/arm/v7/opdefs/lsl_A8894.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,76 +23,69 @@ @title LSL (immediate) -@encoding(t1) { +@desc Logical Shift Left (immediate) shifts a register value left by an immediate number of bits, shifting in zeros, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 0 0 imm5(5) Rm(3) Rd(3) +@encoding (t1) { - @syntax <Rgd> <Rgm> <shiftv> + @half 0 0 0 0 0 imm5(5) Rm(3) Rd(3) - @conv { + @syntax "lsls" <reg_D> <reg_M> <shift_imm> - Rgd = Register(Rd) - Rgm = Register(Rm) - shiftv = DecodeImmShiftValue(imm5) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) + shift_imm = DecodeImmShift('00', imm5) - @rules { - - if (imm5 == '00000') ; see MOV (register, Thumb) - //if (imm5 == '00000') ; see MOV (register) - - } + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 0 0 Rm(4) + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 0 0 Rm(4) - @syntax {s} <Rgd> <Rgm> <shiftv> + @syntax <reg_D> <reg_M> <shift_imm> - @conv { + @conv { - S = SetFlags(S) - Rgd = Register(Rd) - Rgm = Register(Rm) - shiftv = DecodeImmShiftValue(imm3:imm2) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('00', imm3:imm2) - } + } - @rules { + @rules { - if ((imm3 == '000') && (imm2 == '00')) ; see MOV (register, Thumb) - //if ((imm3 == '000') && (imm2 == '00')) ; see MOV (register, Thumb) - //if (imm3:imm2) == '00000' then SEE MOV (register); - //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 0 0 0 Rm(4) + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 0 0 0 Rm(4) - @syntax {S} {c} <Rgd> <Rgm> <shiftv> + @syntax <reg_D> <reg_M> <shift_imm> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rgd = Register(Rd) - Rgm = Register(Rm) - shiftv = DecodeImmShiftValue(imm5) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('00', imm5) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - //if imm5 == '00000' then SEE MOV (register); + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/lsl_A8895.d b/src/arch/arm/v7/opdefs/lsl_A8895.d new file mode 100644 index 0000000..4ac5ab6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/lsl_A8895.d @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LSL (register) + +@desc Logical Shift Left (register) shifts a register value left by a variable number of bits, shifting in zeros, and writes the result to the destination register. The variable number of bits is read from the bottom byte of a register. It can optionally update the condition flags based on the result. + +@encoding (t1) { + + @half 0 1 0 0 0 0 0 0 1 0 Rm(3) Rdn(3) + + @syntax "lsls" <reg_DN> <reg_M> + + @conv { + + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 0 0 0 S(1) Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) Rm(4) 0 0 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/lsr_A8896.d b/src/arch/arm/v7/opdefs/lsr_A8896.d index 8e3f274..acb9e25 100644 --- a/src/arch/arm/v7/opdefs/lsr_A8896.d +++ b/src/arch/arm/v7/opdefs/lsr_A8896.d @@ -23,76 +23,69 @@ @title LSR (immediate) -@encoding(t1) { +@desc Logical Shift Right (immediate) shifts a register value right by an immediate number of bits, shifting in zeros, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 0 1 imm5(5) Rm(3) Rd(3) +@encoding (t1) { - @syntax <Rgd> <Rgm> <shift> + @half 0 0 0 0 1 imm5(5) Rm(3) Rd(3) - @conv { + @syntax "lsrs" <reg_D> <reg_M> <shift_imm> - Rgd = Register(Rd) - Rgm = Register(Rm) - shift = DecodeImmShift(1, imm5) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) + shift_imm = DecodeImmShift('01', imm5) - @rules { - - if (imm5 == '00000') ; see MOV (register, Thumb) - //if (imm5 == '00000') ; see MOV (register) - - } + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 0 1 Rm(4) + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 0 1 Rm(4) - @syntax {s} <Rgd> <Rgm> <shift> + @syntax <reg_D> <reg_M> <shift_imm> - @conv { + @conv { - S = SetFlags(S) - Rgd = Register(Rd) - Rgm = Register(Rm) - shift = DecodeImmShift(1, imm3:imm2) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('01', imm3:imm2) - } + } - @rules { + @rules { - if ((imm3 == '000') && (imm2 == '00')) ; see MOV (register, Thumb) - //if ((imm3 == '000') && (imm2 == '00')) ; see MOV (register, Thumb) - //if (imm3:imm2) == '00000' then SEE MOV (register); - //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 0 1 0 Rm(4) + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 0 1 0 Rm(4) - @syntax {S} {c} <Rgd> <Rgm> <shift> + @syntax <reg_D> <reg_M> <shift_imm> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rgd = Register(Rd) - Rgm = Register(Rm) - shift = DecodeImmShift(1, imm5) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('01', imm5) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; - //if imm5 == '00000' then SEE MOV (register); + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/lsr_A8897.d b/src/arch/arm/v7/opdefs/lsr_A8897.d new file mode 100644 index 0000000..070a152 --- /dev/null +++ b/src/arch/arm/v7/opdefs/lsr_A8897.d @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title LSR (register) + +@desc Logical Shift Right (register) shifts a register value right by a variable number of bits, shifting in zeros, and writes the result to the destination register. The variable number of bits is read from the bottom byte of a register. It can optionally update the condition flags based on the result. + +@encoding (t1) { + + @half 0 1 0 0 0 0 0 0 1 1 Rm(3) Rdn(3) + + @syntax "lsrs" <reg_DN> <reg_M> + + @conv { + + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 0 0 1 S(1) Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) Rm(4) 0 0 1 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/mcr_A8898.d b/src/arch/arm/v7/opdefs/mcr_A8898.d new file mode 100644 index 0000000..f710d5d --- /dev/null +++ b/src/arch/arm/v7/opdefs/mcr_A8898.d @@ -0,0 +1,109 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title MCR, MCR2 + +@desc Move to Coprocessor from ARM core register passes the value of an ARM core register to a coprocessor. If no coprocessor can execute the instruction, an Undefined Instruction exception is generated. This is a generic coprocessor instruction. Some of the fields have no functionality defined by the architecture and are free for use by the coprocessor instruction set designer. These are the opc1, opc2, CRn, and CRm fields. However, coprocessors CP8-CP15 are reserved for use by ARM, and this manual defines the valid MCR and MCR2 instructions when coproc is in the range p8-p15. For more information see Coprocessor support on page A2-94. In an implementation that includes the Virtualization Extensions, MCR accesses to system control registers can be trapped to Hyp mode, meaning that an attempt to execute an MCR instruction in a Non-secure mode other than Hyp mode, that would be permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see Traps to the hypervisor on page B1-1247. Note Because of the range of possible traps to Hyp mode, the MCR pseudocode does not show these possible traps. + +@encoding (T1) { + + @word 1 1 1 0 1 1 1 0 opc1(3) 0 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + +@encoding (A1) { + + @word cond(4) 1 1 1 0 opc1(3) 0 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 1 1 0 opc1(3) 0 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax "mcr2" <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + +@encoding (A2) { + + @word 1 1 1 1 1 1 1 0 opc1(3) 0 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax "mcr2" <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/mcrr_A8899.d b/src/arch/arm/v7/opdefs/mcrr_A8899.d new file mode 100644 index 0000000..f643826 --- /dev/null +++ b/src/arch/arm/v7/opdefs/mcrr_A8899.d @@ -0,0 +1,105 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title MCRR, MCRR2 + +@desc Move to Coprocessor from two ARM core registers passes the values of two ARM core registers to a coprocessor. If no coprocessor can execute the instruction, an Undefined Instruction exception is generated. This is a generic coprocessor instruction. Some of the fields have no functionality defined by the architecture and are free for use by the coprocessor instruction set designer. These are the opc1 and CRm fields. However, coprocessors CP8-CP15 are reserved for use by ARM, and this manual defines the valid MCRR and MCRR2 instructions when coproc is in the range p8-p15. For more information see Coprocessor support on page A2-94. In an implementation that includes the Virtualization Extensions, MCRR accesses to system control registers can be trapped to Hyp mode, meaning that an attempt to execute an MCRR instruction in a Non-secure mode other than Hyp mode, that would be permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see Traps to the hypervisor on page B1-1247. Note Because of the range of possible traps to Hyp mode, the MCRR pseudocode does not show these possible traps. + +@encoding (T1) { + + @word 1 1 1 0 1 1 0 0 0 1 0 0 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax <cp> <undef_opc1> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_M = CRegister(CRm) + + } + +} + +@encoding (A1) { + + @word cond(4) 1 1 0 0 0 1 0 0 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax <cp> <undef_opc1> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_M = CRegister(CRm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 1 0 0 0 1 0 0 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax "mcrr2" <cp> <undef_opc1> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_M = CRegister(CRm) + + } + +} + +@encoding (A2) { + + @word 1 1 1 1 1 1 0 0 0 1 0 0 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax "mcrr2" <cp> <undef_opc1> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_M = CRegister(CRm) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/mla_A88100.d b/src/arch/arm/v7/opdefs/mla_A88100.d index 2683e3a..5d4b4e4 100644 --- a/src/arch/arm/v7/opdefs/mla_A88100.d +++ b/src/arch/arm/v7/opdefs/mla_A88100.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,51 +23,47 @@ @title MLA -@encoding(T1) { +@desc Multiply Accumulate multiplies two register values, and adds a third register value. The least significant 32 bits of the result are written to the destination register. These 32 bits do not depend on whether the source register values are considered to be signed values or unsigned values. In an ARM instruction, the condition flags can optionally be updated based on the result. Use of this option adversely affects performance on many processor implementations. - @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 0 Rm(4) +@encoding (T1) { - @syntax <Rd> <Rn> <Rm> <Ra> + @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 0 Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <reg_A> - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - Ra = Register(Ra) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) - @rules { - - //if (Ra == '1111') ; see MUL - //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 0 1 S(1) Rd(4) Ra(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 0 0 1 S(1) Rd(4) Ra(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <Ra> + @syntax <reg_D> <reg_N> <reg_M> <reg_A> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - Ra = Register(Ra) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + setflags = (S == '1') - } + } - @rules { + @rules { - //if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mls_A88101.d b/src/arch/arm/v7/opdefs/mls_A88101.d index 3d55f00..4d10be8 100644 --- a/src/arch/arm/v7/opdefs/mls_A88101.d +++ b/src/arch/arm/v7/opdefs/mls_A88101.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,49 +23,45 @@ @title MLS -@encoding(T1) { +@desc Multiply and Subtract multiplies two register values, and subtracts the product from a third register value. The least significant 32 bits of the result are written to the destination register. These 32 bits do not depend on whether the source register values are considered to be signed values or unsigned values. - @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 1 Rm(4) +@encoding (T1) { - @syntax <Rd> <Rn> <Rm> <Ra> + @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 1 Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <reg_A> - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - Ra = Register(Ra) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) - @rules { - - //if d IN {13,15} || n IN {13,15} || m IN {13,15} || a IN {13,15} then UNPREDICTABLE - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 1 1 0 Rd(4) Ra(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 0 1 1 0 Rd(4) Ra(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {c} <Rd> <Rn> <Rm> <Ra> + @syntax <reg_D> <reg_N> <reg_M> <reg_A> - @conv { + @conv { - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - Ra = Register(Ra) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) - } + } - @rules { + @rules { - //if d == 15 || n == 15 || m == 15 || a == 15 then UNPREDICTABLE; + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mov_A88102.d b/src/arch/arm/v7/opdefs/mov_A88102.d index ae67b22..d96baab 100644 --- a/src/arch/arm/v7/opdefs/mov_A88102.d +++ b/src/arch/arm/v7/opdefs/mov_A88102.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,105 +23,102 @@ @title MOV (immediate) -@encoding(t1) { +@desc Move (immediate) writes an immediate value to the destination register. It can optionally update the condition flags based on the value. - @half 0 0 1 0 0 Rd(3) imm8(8) +@encoding (t1) { - @syntax <Rd> <const> + @half 0 0 1 0 0 Rd(3) imm8(8) - @conv { + @syntax "movs" <reg_D> <imm32> - Rd = Register(Rd) - const = ZeroExtend(imm8, 8, 32) + @conv { - } + reg_D = Register(Rd) + imm32 = ZeroExtend(imm8, 32) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 i(1) 0 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 0 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm8(8) - @syntax {S} ".W" <Rd> <const> + @syntax <reg_D> <imm32> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - } + } - @rules { + @rules { - //if d IN {13,15} then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(T3) { - - @word 1 1 1 1 0 i(1) 1 0 0 1 0 0 imm4(4) 0 imm3(3) Rd(4) imm8(8) - - @syntax <Rd> <const> +@encoding (T3) { - @conv { + @word 1 1 1 1 0 i(1) 1 0 0 1 0 0 imm4(4) 0 imm3(3) Rd(4) imm8(8) - Rd = Register(Rd) - const = ZeroExtend(imm4:i:imm3:imm8, 12, 32) + @syntax "movw" <reg_D> <imm32> - } + @conv { - @rules { + reg_D = Register(Rd) + imm32 = ZeroExtend(imm4:i:imm3:imm8, 32) - //if d IN {13,15} then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm12(12) + @word cond(4) 0 0 1 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm12(12) - @syntax {S} {c} <Rd> <const> + @syntax <reg_D> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - const = ARMExpandImm_C(imm12, 0) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ARMExpandImm_C(imm12, 0) - } + } - @rules { + @rules { - if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions (ARM) + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } -@encoding(A2) { +@encoding (A2) { - @word cond(4) 0 0 1 1 0 0 0 0 imm4(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 1 0 0 0 0 imm4(4) Rd(4) imm12(12) - @syntax "movw" {c} <Rd> <const> + @syntax "movw" <reg_D> <imm32> - @conv { + @conv { - c = Condition(cond) - Rd = Register(Rd) - const = ZeroExtend(imm4:imm12, 16, 32) + reg_D = Register(Rd) + imm32 = ZeroExtend(imm4:imm12, 32) - } + } - @rules { + @rules { - //if d == 15 then UNPREDICTABLE; + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mov_A88103.d b/src/arch/arm/v7/opdefs/mov_A88103.d index d1f9b9c..cd3d75a 100644 --- a/src/arch/arm/v7/opdefs/mov_A88103.d +++ b/src/arch/arm/v7/opdefs/mov_A88103.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,68 +23,58 @@ @title MOV (register, Thumb) -@encoding(t1) { +@desc Move (register) copies a value from a register to the destination register. It can optionally update the condition flags based on the value. - @half 0 1 0 0 0 1 1 0 D(1) Rm(4) Rd(3) +@encoding (t1) { - @syntax <Rgd> <Rgm> + @half 0 1 0 0 0 1 1 0 D(1) Rm(4) Rd(3) - @conv { + @syntax <reg_D> <reg_M> - Rgd = Register(D:Rd) - Rgm = Register(Rm) + @conv { - } + reg_D = Register(D:Rd) + reg_M = Register(Rm) - @rules { - - //if d == 15 && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - - } + } } -@encoding(t2) { - - @half 0 0 0 0 0 0 0 0 0 0 Rm(3) Rd(3) +@encoding (t2) { - @syntax <Rgd> <Rgm> + @half 0 0 0 0 0 0 0 0 0 0 Rm(3) Rd(3) - @conv { + @syntax "movs" <reg_D> <reg_M> - S = SetFlags(1) - Rgd = Register(Rd) - Rgm = Register(Rm) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) - @rules { - - //if InITBlock() then UNPREDICTABLE; - - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 0 0 0 Rd(4) 0 0 0 0 Rm(4) + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 0 0 0 Rd(4) 0 0 0 0 Rm(4) - @syntax {S} <Rgd> <Rgm> + @syntax <reg_D> <reg_M> - @conv { + @conv { - S = SetFlags(S) - Rgd = Register(Rd) - Rgm = Register(Rm) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') - } + } - @rules { + @rules { - //if setflags && (d IN {13,15} || m IN {13,15}) then UNPREDICTABLE; - //if !setflags && (d == 15 || m == 15 || (d == 13 && m == 13)) then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } + diff --git a/src/arch/arm/v7/opdefs/mov_A88104.d b/src/arch/arm/v7/opdefs/mov_A88104.d index 1efebd3..d164983 100644 --- a/src/arch/arm/v7/opdefs/mov_A88104.d +++ b/src/arch/arm/v7/opdefs/mov_A88104.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,25 +23,28 @@ @title MOV (register, ARM) -@encoding(A1) { +@desc Move (register) copies a value from a register to the destination register. It can optionally update the condition flags based on the value. - @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) 0 0 0 0 0 0 0 0 Rm(4) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rm> + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) 0 0 0 0 0 0 0 0 Rm(4) - @conv { + @syntax <reg_D> <reg_M> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rm = Register(Rm) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') - @rules { + } - if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions (ARM) + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/movt_A88106.d b/src/arch/arm/v7/opdefs/movt_A88106.d index a5ad4f1..265d008 100644 --- a/src/arch/arm/v7/opdefs/movt_A88106.d +++ b/src/arch/arm/v7/opdefs/movt_A88106.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,45 +23,41 @@ @title MOVT -@encoding(T1) { +@desc Move Top writes an immediate value to the top halfword of the destination register. It does not affect the contents of the bottom halfword. - @word 1 1 1 1 0 i(1) 1 0 1 1 0 0 imm4(4) 0 imm3(3) Rd((4) imm8(8) +@encoding (T1) { - @syntax <Rd> <imm16> + @word 1 1 1 1 0 i(1) 1 0 1 1 0 0 imm4(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <imm16> - Rd = Register(Rd) - imm16 = Imm16(imm4:i:imm3:imm8) + @conv { - } + reg_D = Register(Rd) + imm16 = BuildImm16(imm4:i:imm3:imm8) - @rules { - - //if d IN {13,15} then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 1 0 1 0 0 imm4(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 1 0 1 0 0 imm4(4) Rd(4) imm12(12) - @syntax {c} <Rd> <imm16> + @syntax <reg_D> <imm16> - @conv { + @conv { - c = Condition(cond) - Rd = Register(Rd) - imm16 = Imm16(imm4:imm12) + reg_D = Register(Rd) + imm16 = BuildImm16(imm4:imm12) - } + } - @rules { + @rules { - //if d == 15 then UNPREDICTABLE; + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mrc_A88107.d b/src/arch/arm/v7/opdefs/mrc_A88107.d new file mode 100644 index 0000000..fb9714c --- /dev/null +++ b/src/arch/arm/v7/opdefs/mrc_A88107.d @@ -0,0 +1,109 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title MRC, MRC2 + +@desc Move to ARM core register from Coprocessor causes a coprocessor to transfer a value to an ARM core register or to the condition flags. If no coprocessor can execute the instruction, an Undefined Instruction exception is generated. This is a generic coprocessor instruction. Some of the fields have no functionality defined by the architecture and are free for use by the coprocessor instruction set designer. These are the opc1, opc2, CRn, and CRm fields. However, coprocessors CP8-CP15 are reserved for use by ARM, and this manual defines the valid MRC and MRC2 instructions when coproc is in the range p8-p15. For more information see Coprocessor support on page A2-94. In an implementation that includes the Virtualization Extensions, MRC accesses to system control registers can be trapped to Hyp mode, meaning that an attempt to execute an MRC instruction in a Non-secure mode other than Hyp mode, that would be permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see Traps to the hypervisor on page B1-1247. Note Because of the range of possible traps to Hyp mode, the MRC pseudocode does not show these possible traps. + +@encoding (T1) { + + @word 1 1 1 0 1 1 1 0 opc1(3) 1 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + +@encoding (A1) { + + @word cond(4) 1 1 1 0 opc1(3) 1 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 1 1 0 opc1(3) 1 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax "mrc2" <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + +@encoding (A2) { + + @word 1 1 1 1 1 1 1 0 opc1(3) 1 CRn(4) Rt(4) coproc(4) opc2(3) 1 CRm(4) + + @syntax "mrc2" <cp> <undef_opc1> <reg_T> <creg_N> <creg_M> <?undef_opc2> + + @conv { + + reg_T = Register(Rt) + cp = CoProcessor(coproc) + undef_opc1 = RawValue(opc1) + creg_N = CRegister(CRn) + creg_M = CRegister(CRm) + undef_opc2 = RawValue(opc2) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/mrrc_A88108.d b/src/arch/arm/v7/opdefs/mrrc_A88108.d new file mode 100644 index 0000000..026c0ef --- /dev/null +++ b/src/arch/arm/v7/opdefs/mrrc_A88108.d @@ -0,0 +1,105 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title MRRC, MRRC2 + +@desc Move to two ARM core registers from Coprocessor causes a coprocessor to transfer values to two ARM core registers. If no coprocessor can execute the instruction, an Undefined Instruction exception is generated. This is a generic coprocessor instruction. Some of the fields have no functionality defined by the architecture and are free for use by the coprocessor instruction set designer. These are the opc1 and CRm fields. However, coprocessors CP8-CP15 are reserved for use by ARM, and this manual defines the valid MRRC and MRRC2 instructions when coproc is in the range p8-p15. For more information see Coprocessor support on page A2-94. In an implementation that includes the Virtualization Extensions, MRRC accesses to system control registers can be trapped to Hyp mode, meaning that an attempt to execute an MRRC instruction in a Non-secure mode other than Hyp mode, that would be permitted in the absence of the Hyp trap controls, generates a Hyp Trap exception. For more information, see Traps to the hypervisor on page B1-1247. Note Because of the range of possible traps to Hyp mode, the MRRC pseudocode does not show these possible traps. + +@encoding (T1) { + + @word 1 1 1 0 1 1 0 0 0 1 0 1 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax <cp> <opc> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + opc = RawValue(opc1) + creg_M = CRegister(CRm) + + } + +} + +@encoding (A1) { + + @word cond(4) 1 1 0 0 0 1 0 1 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax <cp> <opc> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + opc = RawValue(opc1) + creg_M = CRegister(CRm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 1 0 0 0 1 0 1 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax "mrrc2" <cp> <opc> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + opc = RawValue(opc1) + creg_M = CRegister(CRm) + + } + +} + +@encoding (A2) { + + @word 1 1 1 1 1 1 0 0 0 1 0 1 Rt2(4) Rt(4) coproc(4) opc1(4) CRm(4) + + @syntax "mrrc2" <cp> <opc> <reg_T> <reg_T2> <creg_M> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + cp = CoProcessor(coproc) + opc = RawValue(opc1) + creg_M = CRegister(CRm) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/mul_A88114.d b/src/arch/arm/v7/opdefs/mul_A88114.d index fb4fb43..fa250b7 100644 --- a/src/arch/arm/v7/opdefs/mul_A88114.d +++ b/src/arch/arm/v7/opdefs/mul_A88114.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,63 +23,61 @@ @title MUL -@encoding(t1) { +@desc Multiply multiplies two register values. The least significant 32 bits of the result are written to the destination register. These 32 bits do not depend on whether the source register values are considered to be signed values or unsigned values. Optionally, it can update the condition flags based on the result. In the Thumb instruction set, this option is limited to only a few forms of the instruction. Use of this option adversely affects performance on many processor implementations. - @half 0 1 0 0 0 0 1 1 0 1 Rn(3) Rdm(3) +@encoding (t1) { - @syntax <Rdm> <Rn> <Rdm> + @half 0 1 0 0 0 0 1 1 0 1 Rn(3) Rdm(3) - @conv { + @syntax "muls" <reg_DM_1> <reg_N> <reg_DM_2> - Rdm = Register(Rdm) - Rn = Register(Rn) + @conv { - } + reg_N = Register(Rn) + reg_DM_1 = Register(Rdm) + reg_DM_2 = Register(Rdm) -} - -@encoding(T2) { - - @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + } - @syntax <Rd> <Rn> <Rm> +} - @conv { +@encoding (T2) { - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) + @word 1 1 1 1 1 0 1 1 0 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) - } + @syntax <reg_D> <reg_N> <reg_M> - @rules { + @conv { - //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 0 0 S(1) Rd(4) 0 0 0 0 Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 0 0 0 S(1) Rd(4) 0 0 0 0 Rm(4) 1 0 0 1 Rn(4) - @syntax {S} {c} <Rd> <Rn> <Rm> + @syntax <reg_D> <reg_N> <reg_M> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') - } + } - @rules { + @rules { - //if d == 15 || n == 15 || m == 15 then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mvn_A88115.d b/src/arch/arm/v7/opdefs/mvn_A88115.d index 32e96b3..2955439 100644 --- a/src/arch/arm/v7/opdefs/mvn_A88115.d +++ b/src/arch/arm/v7/opdefs/mvn_A88115.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,47 +23,50 @@ @title MVN (immediate) -@encoding(T1) { +@desc Bitwise NOT (immediate) writes the bitwise inverse of an immediate value to the destination register. It can optionally update the condition flags based on the value. - @word 1 1 1 1 0 i(1) 0 0 0 1 1 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <const> + @word 1 1 1 1 0 i(1) 0 0 0 1 1 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - //if (d IN {13,15}) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 1 1 1 1 S(1) 0 0 0 0 Rd(4) imm12(12) + @word cond(4) 0 0 1 1 1 1 1 S(1) 0 0 0 0 Rd(4) imm12(12) - @syntax {S} {c} <Rd> <const> + @syntax <reg_D> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - const = ARMExpandImm_C(imm12, 0) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ARMExpandImm_C(imm12, 0) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mvn_A88116.d b/src/arch/arm/v7/opdefs/mvn_A88116.d index 3c97db4..1f3f390 100644 --- a/src/arch/arm/v7/opdefs/mvn_A88116.d +++ b/src/arch/arm/v7/opdefs/mvn_A88116.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,64 +23,68 @@ @title MVN (register) -@encoding(t1) { +@desc Bitwise NOT (register) writes the bitwise inverse of a register value to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 1 1 1 1 Rm(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rm> + @half 0 1 0 0 0 0 1 1 1 1 Rm(3) Rd(3) - @conv { + @syntax "mvns" <reg_D> <reg_M> - Rd = Register(Rd) - Rm = Register(Rm) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 1 1 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 0 0 1 1 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rm> <?shift> + @syntax <reg_D> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 1 1 1 S(1) 0 0 0 0 Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 1 1 1 1 S(1) 0 0 0 0 Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rm> <?shift> + @syntax <reg_D> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/mvn_A88117.d b/src/arch/arm/v7/opdefs/mvn_A88117.d new file mode 100644 index 0000000..cc6ef16 --- /dev/null +++ b/src/arch/arm/v7/opdefs/mvn_A88117.d @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title MVN (register-shifted register) + +@desc Bitwise NOT (register-shifted register) writes the bitwise inverse of a register-shifted register value to the destination register. It can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 1 1 S(1) 0 0 0 0 Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/nop_A88119.d b/src/arch/arm/v7/opdefs/nop_A88119.d index d47c346..84c495a 100644 --- a/src/arch/arm/v7/opdefs/nop_A88119.d +++ b/src/arch/arm/v7/opdefs/nop_A88119.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,28 +23,31 @@ @title NOP -@encoding(t1) { +@desc No Operation does nothing. This instruction can be used for instruction alignment purposes. See Pre-UAL pseudo-instruction NOP on page AppxH-2472 for details of NOP before the introduction of UAL and the ARMv6K and ARMv6T2 architecture variants. Note The timing effects of including a NOP instruction in a program are not guaranteed. It can increase execution time, leave it unchanged, or even reduce it. Therefore, NOP instructions are not suitable for timing loops. - @half 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 +@encoding (t1) { + + @half 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -} + @syntax ".W" -@encoding(A1) { +} - @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 +@encoding (A1) { - @syntax {c} + @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 - @conv { + @rules { - c = Condition(cond) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/orn_A88120.d b/src/arch/arm/v7/opdefs/orn_A88120.d new file mode 100644 index 0000000..b823b6c --- /dev/null +++ b/src/arch/arm/v7/opdefs/orn_A88120.d @@ -0,0 +1,50 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ORN (immediate) + +@desc Bitwise OR NOT (immediate) performs a bitwise (inclusive) OR of a register value and the complement of an immediate value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (T1) { + + @word 1 1 1 1 0 i(1) 0 0 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + + @syntax <reg_D> <reg_N> <imm32> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + + } + +} + diff --git a/src/arch/arm/v7/opdefs/orn_A88121.d b/src/arch/arm/v7/opdefs/orn_A88121.d new file mode 100644 index 0000000..f1523ec --- /dev/null +++ b/src/arch/arm/v7/opdefs/orn_A88121.d @@ -0,0 +1,51 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ORN (register) + +@desc Bitwise OR NOT (register) performs a bitwise (inclusive) OR of a register value and the complement of an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (T1) { + + @word 1 1 1 0 1 0 1 0 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + + } + +} + diff --git a/src/arch/arm/v7/opdefs/orr_A88122.d b/src/arch/arm/v7/opdefs/orr_A88122.d index 937c902..766b5ee 100644 --- a/src/arch/arm/v7/opdefs/orr_A88122.d +++ b/src/arch/arm/v7/opdefs/orr_A88122.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,50 +23,52 @@ @title ORR (immediate) -@encoding(T1) { +@desc Bitwise OR (immediate) performs a bitwise (inclusive) OR of a register value and an immediate value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word 1 1 1 1 0 i(1) 0 0 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <const> + @word 1 1 1 1 0 i(1) 0 0 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - if (Rn == '1111') ; see MOV (immediate) - //if ((d IN {13,15}) || (n == 13)) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 1 1 0 0 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 1 1 0 0 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm_C(imm12, 0) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm_C(imm12, 0) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/orr_A88123.d b/src/arch/arm/v7/opdefs/orr_A88123.d index 978a751..2395c89 100644 --- a/src/arch/arm/v7/opdefs/orr_A88123.d +++ b/src/arch/arm/v7/opdefs/orr_A88123.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,67 +23,70 @@ @title ORR (register) -@encoding(t1) { +@desc Bitwise OR (register) performs a bitwise (inclusive) OR of a register value and an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 1 1 0 0 Rm(3) Rdn(3) +@encoding (t1) { - @syntax <Rdn> <Rm> + @half 0 1 0 0 0 0 1 1 0 0 Rm(3) Rdn(3) - @conv { + @syntax "orrs" <reg_DN> <reg_M> - Rdn = Register(Rdn) - Rm = Register(Rm) + @conv { - } + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 0 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if Rn == '1111' then SEE "Related encodings"; - //if d IN {13,15} || n == 13 || m IN {13,15} then UNPREDICTABLE + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 1 0 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 1 1 0 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/orr_A88124.d b/src/arch/arm/v7/opdefs/orr_A88124.d new file mode 100644 index 0000000..f4d78b9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/orr_A88124.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ORR (register-shifted register) + +@desc Bitwise OR (register-shifted register) performs a bitwise (inclusive) OR of a register value and a register-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 0 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/pop_A88131.d b/src/arch/arm/v7/opdefs/pop_A88131.d index 47b9c2d..7de7ee4 100644 --- a/src/arch/arm/v7/opdefs/pop_A88131.d +++ b/src/arch/arm/v7/opdefs/pop_A88131.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,68 +23,47 @@ @title POP (Thumb) -@encoding(t1) { +@desc Pop Multiple Registers loads multiple registers from the stack, loading from consecutive memory locations starting at the address in SP, and updates SP to point just above the loaded data. - @half 1 0 1 1 1 1 0 P(1) register_list(8) +@encoding (t1) { - @syntax <registers> + @half 1 0 1 1 1 1 0 P(1) register_list(8) - @conv { + @syntax <registers> - registers = RegistersList(P:'0000000':register_list) + @conv { - } + registers = RegistersList(P:'0000000':register_list) - @rules { - - //if BitCount(registers) < 1 then UNPREDICTABLE; - //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (P == '1') ; chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(T2) { - - @word 1 1 1 0 1 0 0 0 1 0 1 1 1 1 0 1 P(1) M(1) 0 register_list(13) - - @syntax "pop.W" <registers> - - @conv { +@encoding (T2) { - registers = RegistersList(P:M:'0':register_list) + @word 1 1 1 0 1 0 0 0 1 0 1 1 1 1 0 1 P(1) M(1) 0 register_list(13) - } + @syntax ".W" <registers> - @rules { + @conv { - //if BitCount(registers) < 2 || (P == '1' && M == '1') then UNPREDICTABLE; - //if registers<15> == '1' && InITBlock() && !LastInITBlock() then UNPREDICTABLE; - if (P == '1') ; chk_call SetInsFlag(AIF_RETURN_POINT) + registers = RegistersList(P:M:'0':register_list) - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 Rt(4) 1 0 1 1 0 0 0 0 0 1 0 0 + @word 1 1 1 1 1 0 0 0 0 1 0 1 1 1 0 1 Rt(4) 1 0 1 1 0 0 0 0 0 1 0 0 - @syntax "pop.W" <registers> + @syntax ".W" <registers> - @conv { + @conv { - Rgt = Register(Rt) - registers = ListFromRegister(Rgt) + registers = Zeros(16) - } - - @rules { - - //if t == 13 || (t == 15 && InITBlock() && !LastInITBlock()) then UNPREDICTABLE; - if (Rt == '1111') ; chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/pop_A88132.d b/src/arch/arm/v7/opdefs/pop_A88132.d index 10e18a4..692aecb 100644 --- a/src/arch/arm/v7/opdefs/pop_A88132.d +++ b/src/arch/arm/v7/opdefs/pop_A88132.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,48 +23,45 @@ @title POP (ARM) -@encoding(A1) { +@desc Pop Multiple Registers loads multiple registers from the stack, loading from consecutive memory locations starting at the address in SP, and updates SP to point just above the loaded data. - @word cond(4) 1 0 0 0 1 0 1 1 1 1 0 1 register_list(16) +@encoding (A1) { - @syntax {c} <registers> + @word cond(4) 1 0 0 0 1 0 1 1 1 1 0 1 register_list(16) - @conv { + @syntax <registers> - c = Condition(cond) - registers = RegistersList(register_list) + @conv { - } + registers = RegistersList(register_list) - @rules { + } - //if BitCount(register_list) < 2 then SEE LDM / LDMIA / LDMFD; - //if registers<13> == '1' && ArchVersion() >= 7 then UNPREDICTABLE; - if (register_list & 0x8000) ; chk_call SetInsFlag(AIF_RETURN_POINT) + @rules { - } + chk_call StoreCondition(cond) + + } } -@encoding(A2) { +@encoding (A2) { - @word cond(4) 0 1 0 0 1 0 0 1 1 1 0 1 Rt(4) 0 0 0 0 0 0 0 0 0 1 0 0 + @word cond(4) 0 1 0 0 1 0 0 1 1 1 0 1 Rt(4) 0 0 0 0 0 0 0 0 0 1 0 0 - @syntax {c} <registers> + @syntax <registers> - @conv { + @conv { - c = Condition(cond) - Rgt = Register(Rt) - registers = ListFromRegister(Rgt) + registers = Zeros(16) - } + } - @rules { + @rules { - //if t == 13 then UNPREDICTABLE; - if (Rt == '1111') ; chk_call SetInsFlag(AIF_RETURN_POINT) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/push_A88133.d b/src/arch/arm/v7/opdefs/push_A88133.d index 2ba7293..14fc3e9 100644 --- a/src/arch/arm/v7/opdefs/push_A88133.d +++ b/src/arch/arm/v7/opdefs/push_A88133.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,116 +23,87 @@ @title PUSH -@encoding(t1) { +@desc Push Multiple Registers stores multiple registers to the stack, storing to consecutive memory locations ending just below the address in SP, and updates SP to point to the start of the stored data. - @half 1 0 1 1 0 1 0 M(1) register_list(8) +@encoding (t1) { - @syntax <registers> + @half 1 0 1 1 0 1 0 M(1) register_list(8) - @conv { + @syntax <registers> - registers = RegistersList('0':M:'000000':register_list) + @conv { - } + registers = RegistersList('0':M:'000000':register_list) - @rules { - - //if BitCount(registers) < 1 then UNPREDICTABLE; - - if (M == '1'); call SetInsFlag(AIF_ROUTINE_START); - - } + } } -@encoding(T2) { - - @word 1 1 1 0 1 0 0 1 0 0 1 0 1 1 0 1 0 M(1) 0 register_list(13) - - @syntax "push.W" <registers> - - @conv { - - registers = RegistersList('0':M:'0':register_list) +@encoding (T2) { - } + @word 1 1 1 0 1 0 0 1 0 0 1 0 1 1 0 1 0 M(1) 0 register_list(13) - @rules { + @syntax ".W" <registers> - //if BitCount(registers) < 2 then UNPREDICTABLE; + @conv { - if (M == '1'); call SetInsFlag(AIF_ROUTINE_START); + registers = RegistersList('0':M:'0':register_list) - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1 Rt(4) 1 1 0 1 0 0 0 0 0 1 0 0 + @word 1 1 1 1 1 0 0 0 0 1 0 0 1 1 0 1 Rt(4) 1 1 0 1 0 0 0 0 0 1 0 0 - @syntax "push.W" <registers> + @syntax ".W" <registers> - @conv { + @conv { - Rgt = Register(Rt) - registers = ListFromRegister(Rgt) + registers = Zeros(16) - } - - @rules { - - //if t IN {13,15} then UNPREDICTABLE - - if (Rt == '1110'); call SetInsFlag(AIF_ROUTINE_START); - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 1 0 0 1 0 0 1 0 1 1 0 1 register_list(16) + @word cond(4) 1 0 0 1 0 0 1 0 1 1 0 1 register_list(16) - @syntax {c} <registers> + @syntax <registers> - @conv { + @conv { - c = Condition(cond) - registers = RegistersList(register_list) + registers = RegistersList(register_list) - } + } - @rules { + @rules { - //if BitCount(register_list) < 2 then SEE STMDB / STMFD; + chk_call StoreCondition(cond) - if (register_list & 0x4000); call SetInsFlag(AIF_ROUTINE_START); - - } + } } -@encoding(A2) { - - @word cond(4) 0 1 0 1 0 0 1 0 1 1 0 1 Rt(4) 0 0 0 0 0 0 0 0 0 1 0 0 +@encoding (A2) { - @syntax {c} <registers> + @word cond(4) 0 1 0 1 0 0 1 0 1 1 0 1 Rt(4) 0 0 0 0 0 0 0 0 0 1 0 0 - @conv { + @syntax <registers> - c = Condition(cond) - Rgt = Register(Rt) - registers = ListFromRegister(Rgt) + @conv { - } + registers = Zeros(16) - @rules { + } - //if t == 13 then UNPREDICTABLE; + @rules { - if (Rt == '1110'); call SetInsFlag(AIF_ROUTINE_START); + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/qadd16_A88135.d b/src/arch/arm/v7/opdefs/qadd16_A88135.d new file mode 100644 index 0000000..15af29d --- /dev/null +++ b/src/arch/arm/v7/opdefs/qadd16_A88135.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QADD16 + +@desc Saturating Add 16 performs two 16-bit integer additions, saturates the results to the 16-bit signed integer range –215 ≤ x ≤ 215 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 0 Rn(4) Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qadd8_A88136.d b/src/arch/arm/v7/opdefs/qadd8_A88136.d new file mode 100644 index 0000000..a71b251 --- /dev/null +++ b/src/arch/arm/v7/opdefs/qadd8_A88136.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QADD8 + +@desc Saturating Add 8 performs four 8-bit integer additions, saturates the results to the 8-bit signed integer range –27 ≤ x ≤ 27 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 0 Rn(4) Rd(4) 1 1 1 1 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qadd_A88134.d b/src/arch/arm/v7/opdefs/qadd_A88134.d new file mode 100644 index 0000000..f932983 --- /dev/null +++ b/src/arch/arm/v7/opdefs/qadd_A88134.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QADD + +@desc Saturating Add adds two register values, saturates the result to the 32-bit signed integer range –231 to (231 – 1), and writes the result to the destination register. If saturation occurs, it sets the Q flag in the APSR. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 1 0 0 0 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 0 0 0 Rn(4) Rd(4) 0 0 0 0 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qasx_A88137.d b/src/arch/arm/v7/opdefs/qasx_A88137.d new file mode 100644 index 0000000..68251ca --- /dev/null +++ b/src/arch/arm/v7/opdefs/qasx_A88137.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QASX + +@desc Saturating Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one 16-bit integer addition and one 16-bit subtraction, saturates the results to the 16-bit signed integer range –215 ≤ x ≤ 215 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 0 Rn(4) Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qdadd_A88138.d b/src/arch/arm/v7/opdefs/qdadd_A88138.d new file mode 100644 index 0000000..c40cdcd --- /dev/null +++ b/src/arch/arm/v7/opdefs/qdadd_A88138.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QDADD + +@desc Saturating Double and Add adds a doubled register value to another register value, and writes the result to the destination register. Both the doubling and the addition have their results saturated to the 32-bit signed integer range –231 ≤ x ≤ 231 – 1. If saturation occurs in either operation, it sets the Q flag in the APSR. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 1 0 0 Rn(4) Rd(4) 0 0 0 0 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qdsub_A88139.d b/src/arch/arm/v7/opdefs/qdsub_A88139.d new file mode 100644 index 0000000..87bd083 --- /dev/null +++ b/src/arch/arm/v7/opdefs/qdsub_A88139.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QDSUB + +@desc Saturating Double and Subtract subtracts a doubled register value from another register value, and writes the result to the destination register. Both the doubling and the subtraction have their results saturated to the 32-bit signed integer range –231 ≤ x ≤ 231 – 1. If saturation occurs in either operation, it sets the Q flag in the APSR. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 1 0 1 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 1 1 0 Rn(4) Rd(4) 0 0 0 0 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qsax_A88140.d b/src/arch/arm/v7/opdefs/qsax_A88140.d new file mode 100644 index 0000000..df24cf8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/qsax_A88140.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QSAX + +@desc Saturating Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one 16-bit integer subtraction and one 16-bit addition, saturates the results to the 16-bit signed integer range –215 ≤ x ≤ 215 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 1 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 0 Rn(4) Rd(4) 1 1 1 1 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qsub16_A88142.d b/src/arch/arm/v7/opdefs/qsub16_A88142.d new file mode 100644 index 0000000..5b2c96b --- /dev/null +++ b/src/arch/arm/v7/opdefs/qsub16_A88142.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QSUB16 + +@desc Saturating Subtract 16 performs two 16-bit integer subtractions, saturates the results to the 16-bit signed integer range –215 ≤ x ≤ 215 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 1 Rn(4) 1 1 1 1 Rd(4) 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 0 Rn(4) Rd(4) 1 1 1 1 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qsub8_A88143.d b/src/arch/arm/v7/opdefs/qsub8_A88143.d new file mode 100644 index 0000000..270a99d --- /dev/null +++ b/src/arch/arm/v7/opdefs/qsub8_A88143.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QSUB8 + +@desc Saturating Subtract 8 performs four 8-bit integer subtractions, saturates the results to the 8-bit signed integer range –27 ≤ x ≤ 27 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 0 Rn(4) Rd(4) 1 1 1 1 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/qsub_A88141.d b/src/arch/arm/v7/opdefs/qsub_A88141.d new file mode 100644 index 0000000..c60ec57 --- /dev/null +++ b/src/arch/arm/v7/opdefs/qsub_A88141.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title QSUB + +@desc Saturating Subtract subtracts one register value from another register value, saturates the result to the 32-bit signed integer range –231 ≤ x ≤ 231 – 1, and writes the result to the destination register. If saturation occurs, it sets the Q flag in the APSR. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 1 0 1 0 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 0 1 0 Rn(4) Rd(4) 0 0 0 0 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_M> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/rbit_A88144.d b/src/arch/arm/v7/opdefs/rbit_A88144.d new file mode 100644 index 0000000..7f2bdb6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/rbit_A88144.d @@ -0,0 +1,63 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title RBIT + +@desc Reverse Bits reverses the bit order in a 32-bit register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rm(4) 1 1 1 1 Rd(4) 1 0 1 0 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 1 1 1 1 1 Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/rev16_A88146.d b/src/arch/arm/v7/opdefs/rev16_A88146.d new file mode 100644 index 0000000..53b9a82 --- /dev/null +++ b/src/arch/arm/v7/opdefs/rev16_A88146.d @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title REV16 + +@desc Byte-Reverse Packed Halfword reverses the byte order in each16-bit halfword of a 32-bit register. + +@encoding (t1) { + + @half 1 0 1 1 1 0 1 0 0 1 Rm(3) Rd(3) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rm(4) 1 1 1 1 Rd(4) 1 0 0 1 Rm(4) + + @syntax ".W" <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 0 1 1 1 1 1 1 Rd(4) 1 1 1 1 1 0 1 1 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/rev_A88145.d b/src/arch/arm/v7/opdefs/rev_A88145.d new file mode 100644 index 0000000..2fe305d --- /dev/null +++ b/src/arch/arm/v7/opdefs/rev_A88145.d @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title REV + +@desc Byte-Reverse Word reverses the byte order in a 32-bit register. + +@encoding (t1) { + + @half 1 0 1 1 1 0 1 0 0 0 Rm(3) Rd(3) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rm(4) 1 1 1 1 Rd(4) 1 0 0 0 Rm(4) + + @syntax ".W" <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 0 1 1 1 1 1 1 Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/revsh_A88147.d b/src/arch/arm/v7/opdefs/revsh_A88147.d new file mode 100644 index 0000000..551582c --- /dev/null +++ b/src/arch/arm/v7/opdefs/revsh_A88147.d @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title REVSH + +@desc Byte-Reverse Signed Halfword reverses the byte order in the lower 16-bit halfword of a 32-bit register, and sign-extends the result to 32 bits. + +@encoding (t1) { + + @half 1 0 1 1 1 0 1 0 1 1 Rm(3) Rd(3) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rm(4) 1 1 1 1 Rd(4) 1 0 1 1 Rm(4) + + @syntax ".W" <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 1 1 1 1 1 Rd(4) 1 1 1 1 1 0 1 1 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ror_A88149.d b/src/arch/arm/v7/opdefs/ror_A88149.d new file mode 100644 index 0000000..7e061c6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ror_A88149.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ROR (immediate) + +@desc Rotate Right (immediate) provides the value of the contents of a register rotated by a constant value. The bits that are rotated off the right end are inserted into the vacated bit positions on the left. It can optionally update the condition flags based on the result. + +@encoding (T1) { + + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 imm3(3) Rd(4) imm2(2) 1 1 Rm(4) + + @syntax <reg_D> <reg_M> <shift_imm> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('11', imm3:imm2) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) imm5(5) 1 1 0 Rm(4) + + @syntax <reg_D> <reg_M> <shift_imm> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift_imm = DecodeImmShift('11', imm5) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ror_A88150.d b/src/arch/arm/v7/opdefs/ror_A88150.d new file mode 100644 index 0000000..c046bf7 --- /dev/null +++ b/src/arch/arm/v7/opdefs/ror_A88150.d @@ -0,0 +1,90 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title ROR (register) + +@desc Rotate Right (register) provides the value of the contents of a register rotated by a variable number of bits. The bits that are rotated off the right end are inserted into the vacated bit positions on the left. The variable number of bits is read from the bottom byte of a register. It can optionally update the condition flags based on the result. + +@encoding (t1) { + + @half 0 1 0 0 0 0 0 1 1 1 Rm(3) Rdn(3) + + @syntax "rors" <reg_DN> <reg_M> + + @conv { + + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 0 1 1 S(1) Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) Rm(4) 0 1 1 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/rrx_A88151.d b/src/arch/arm/v7/opdefs/rrx_A88151.d new file mode 100644 index 0000000..4debd42 --- /dev/null +++ b/src/arch/arm/v7/opdefs/rrx_A88151.d @@ -0,0 +1,72 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title RRX + +@desc Rotate Right with Extend provides the value of the contents of a register shifted right by one place, with the Carry flag shifted into bit[31]. RRX can optionally update the condition flags based on the result. In that case, bit[0] is shifted into the Carry flag. + +@encoding (T1) { + + @word 1 1 1 0 1 0 1 0 0 1 0 S(1) 1 1 1 1 0 0 0 0 Rd(4) 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 1 1 0 1 S(1) 0 0 0 0 Rd(4) 0 0 0 0 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/rsb_A88152.d b/src/arch/arm/v7/opdefs/rsb_A88152.d index f7bee59..ea53373 100644 --- a/src/arch/arm/v7/opdefs/rsb_A88152.d +++ b/src/arch/arm/v7/opdefs/rsb_A88152.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,65 +23,69 @@ @title RSB (immediate) -@encoding(t1) { +@desc Reverse Subtract (immediate) subtracts a register value from an immediate value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 1 0 0 1 Rn(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rn> <zero> + @half 0 1 0 0 0 0 1 0 0 1 Rn(3) Rd(3) - @conv { + @syntax "rsbs" <reg_D> <reg_N> <imm32> - Rd = Register(Rd) - Rn = Register(Rn) - zero = Zeros(32) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + imm32 = Zeros(32) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 i(1) 0 1 1 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 0 1 1 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @syntax {S} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm(i:imm3:imm8) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) - } + } - @rules { + @rules { - //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 0 1 1 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 0 0 1 1 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/rsb_A88153.d b/src/arch/arm/v7/opdefs/rsb_A88153.d index 0b78c18..f4a6d61 100644 --- a/src/arch/arm/v7/opdefs/rsb_A88153.d +++ b/src/arch/arm/v7/opdefs/rsb_A88153.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,51 +23,54 @@ @title RSB (register) -@encoding(T1) { +@desc Reverse Subtract (register) subtracts a register value from an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word 1 1 1 0 1 0 1 1 1 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @word 1 1 1 0 1 0 1 1 1 1 0 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <?shift> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - @rules { + } - //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 1 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 0 0 1 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/rsb_A88154.d b/src/arch/arm/v7/opdefs/rsb_A88154.d new file mode 100644 index 0000000..9ccf559 --- /dev/null +++ b/src/arch/arm/v7/opdefs/rsb_A88154.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title RSB (register-shifted register) + +@desc Reverse Subtract (register-shifted register) subtracts a register value from a register-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 0 1 1 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/rsc_A88155.d b/src/arch/arm/v7/opdefs/rsc_A88155.d index 440f224..fc5f8b6 100644 --- a/src/arch/arm/v7/opdefs/rsc_A88155.d +++ b/src/arch/arm/v7/opdefs/rsc_A88155.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,26 +23,29 @@ @title RSC (immediate) -@encoding(A1) { +@desc Reverse Subtract with Carry (immediate) subtracts a register value and the value of NOT (Carry flag) from an immediate value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word cond(4) 0 0 1 0 1 1 1 S(1) Rn(4) Rd(4) imm12(12) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rn> <const> + @word cond(4) 0 0 1 0 1 1 1 S(1) Rn(4) Rd(4) imm12(12) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) - @rules { + } - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/rsc_A88156.d b/src/arch/arm/v7/opdefs/rsc_A88156.d index d54d91f..70829cd 100644 --- a/src/arch/arm/v7/opdefs/rsc_A88156.d +++ b/src/arch/arm/v7/opdefs/rsc_A88156.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,27 +23,30 @@ @title RSC (register) -@encoding(A1) { +@desc Reverse Subtract with Carry (register) subtracts a register value and the value of NOT (Carry flag) from an optionally-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word cond(4) 0 0 0 0 1 1 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @word cond(4) 0 0 0 0 1 1 1 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <?shift> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - @rules { + } - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/rsc_A88157.d b/src/arch/arm/v7/opdefs/rsc_A88157.d new file mode 100644 index 0000000..4fa276d --- /dev/null +++ b/src/arch/arm/v7/opdefs/rsc_A88157.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title RSC (register-shifted register) + +@desc Reverse Subtract (register-shifted register) subtracts a register value and the value of NOT (Carry flag) from a register-shifted register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 1 1 1 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sadd16_A88158.d b/src/arch/arm/v7/opdefs/sadd16_A88158.d new file mode 100644 index 0000000..51ad948 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sadd16_A88158.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SADD16 + +@desc Signed Add 16 performs two 16-bit signed integer additions, and writes the results to the destination register. It sets the APSR.GE bits according to the results of the additions. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 0 1 Rn(4) Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sadd8_A88159.d b/src/arch/arm/v7/opdefs/sadd8_A88159.d new file mode 100644 index 0000000..463c968 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sadd8_A88159.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SADD8 + +@desc Signed Add 8 performs four 8-bit signed integer additions, and writes the results to the destination register. It sets the APSR.GE bits according to the results of the additions. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 0 1 Rn(4) Rd(4) 1 1 1 1 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sasx_A88160.d b/src/arch/arm/v7/opdefs/sasx_A88160.d new file mode 100644 index 0000000..a0529cb --- /dev/null +++ b/src/arch/arm/v7/opdefs/sasx_A88160.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SASX + +@desc Signed Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one 16-bit integer addition and one 16-bit subtraction, and writes the results to the destination register. It sets the APSR.GE bits according to the results. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 0 1 Rn(4) Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sbc_A88161.d b/src/arch/arm/v7/opdefs/sbc_A88161.d index 517ea01..4ea776a 100644 --- a/src/arch/arm/v7/opdefs/sbc_A88161.d +++ b/src/arch/arm/v7/opdefs/sbc_A88161.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,49 +23,52 @@ @title SBC (immediate) -@encoding(T1) { +@desc Subtract with Carry (immediate) subtracts an immediate value and the value of NOT (Carry flag) from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word 1 1 1 1 0 i(1) 0 1 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) +@encoding (T1) { - @syntax {S} <Rd> <Rn> <const> + @word 1 1 1 1 0 i(1) 0 1 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm(i:imm3:imm8) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) - @rules { + } - //if ((d IN {13,15}) || (n IN {13,15})) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 1 1 0 S(1) Rn(4) Rd(4) imm12(12) + @word cond(4) 0 0 1 0 1 1 0 S(1) Rn(4) Rd(4) imm12(12) - @syntax {S} {c} <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/sbc_A88162.d b/src/arch/arm/v7/opdefs/sbc_A88162.d index e49f8a3..b6e660a 100644 --- a/src/arch/arm/v7/opdefs/sbc_A88162.d +++ b/src/arch/arm/v7/opdefs/sbc_A88162.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,66 +23,70 @@ @title SBC (register) -@encoding(t1) { +@desc Subtract with Carry (register) subtracts an optionally-shifted register value and the value of NOT (Carry flag) from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 1 0 0 0 0 0 1 1 0 Rm(3) Rdn(3) +@encoding (t1) { - @syntax <Rdn> <Rm> + @half 0 1 0 0 0 0 0 1 1 0 Rm(3) Rdn(3) - @conv { + @syntax "sbcs" <reg_DN> <reg_M> - Rdn = Register(Rdn) - Rm = Register(Rm) + @conv { - } + reg_DN = Register(Rdn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 1 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 1 0 1 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { + @rules { - //if d IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 1 1 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 0 1 1 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/sbc_A88163.d b/src/arch/arm/v7/opdefs/sbc_A88163.d new file mode 100644 index 0000000..0500edc --- /dev/null +++ b/src/arch/arm/v7/opdefs/sbc_A88163.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SBC (register-shifted register) + +@desc Subtract with Carry (register-shifted register) subtracts a register-shifted register value and the value of NOT (Carry flag) from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 1 1 0 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sbfx_A88164.d b/src/arch/arm/v7/opdefs/sbfx_A88164.d new file mode 100644 index 0000000..486db3c --- /dev/null +++ b/src/arch/arm/v7/opdefs/sbfx_A88164.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SBFX + +@desc Signed Bit Field Extract extracts any number of adjacent bits at any position from a register, sign-extends them to 32 bits, and writes the result to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 0 1 0 0 Rn(4) 0 imm3(3) Rd(4) imm2(2) 0 widthm1(5) + + @syntax <reg_D> <reg_N> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + lsbit = UInt(imm3:imm2) + width = IncWidth(widthm1) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 1 0 1 widthm1(5) Rd(4) lsb(5) 1 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + lsbit = UInt(lsb) + width = IncWidth(widthm1) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sdiv_A88165.d b/src/arch/arm/v7/opdefs/sdiv_A88165.d new file mode 100644 index 0000000..19ebfa9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sdiv_A88165.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SDIV + +@desc Signed Divide divides a 32-bit signed integer register value by a 32-bit signed integer register value, and writes the result to the destination register. The condition flags are not affected. See ARMv7 implementation requirements and options for the divide instructions on page A4-172 for more information about this instruction. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 0 0 1 Rd(4) 1 1 1 1 Rm(4) 0 0 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sel_A88166.d b/src/arch/arm/v7/opdefs/sel_A88166.d new file mode 100644 index 0000000..cb32ed6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sel_A88166.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SEL + +@desc Select Bytes selects each byte of its result from either its first operand or its second operand, according to the values of the GE flags. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 1 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 0 0 0 Rn(4) Rd(4) 1 1 1 1 1 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/setend_A88167.d b/src/arch/arm/v7/opdefs/setend_A88167.d new file mode 100644 index 0000000..e549c50 --- /dev/null +++ b/src/arch/arm/v7/opdefs/setend_A88167.d @@ -0,0 +1,55 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SETEND + +@desc Set Endianness writes a new value to ENDIANSTATE. + +@encoding (t1) { + + @half 1 0 1 1 0 1 1 0 0 1 0 1 E(1) 0 0 0 + + @syntax <set_bigend> + + @conv { + + set_bigend = EndianState(E == '1') + + } + +} + +@encoding (A1) { + + @word 1 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 E(1) 0 0 0 0 0 0 0 0 0 + + @syntax <set_bigend> + + @conv { + + set_bigend = EndianState(E == '1') + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sev_A88168.d b/src/arch/arm/v7/opdefs/sev_A88168.d new file mode 100644 index 0000000..2bd9af4 --- /dev/null +++ b/src/arch/arm/v7/opdefs/sev_A88168.d @@ -0,0 +1,53 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SEV + +@desc Send Event is a hint instruction. It causes an event to be signaled to all processors in the multiprocessor system. For more information, see Wait For Event and Send Event on page B1-1199. + +@encoding (t1) { + + @half 1 0 1 1 1 1 1 1 0 1 0 0 0 0 0 0 + +} + +@encoding (T2) { + + @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 + + @syntax ".W" + +} + +@encoding (A1) { + + @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 1 0 0 + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/shadd16_A88169.d b/src/arch/arm/v7/opdefs/shadd16_A88169.d new file mode 100644 index 0000000..22baa05 --- /dev/null +++ b/src/arch/arm/v7/opdefs/shadd16_A88169.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SHADD16 + +@desc Signed Halving Add 16 performs two signed 16-bit integer additions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 0 0 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 1 Rn(4) Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/shadd8_A88170.d b/src/arch/arm/v7/opdefs/shadd8_A88170.d new file mode 100644 index 0000000..bfc3031 --- /dev/null +++ b/src/arch/arm/v7/opdefs/shadd8_A88170.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SHADD8 + +@desc Signed Halving Add 8 performs four signed 8-bit integer additions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 1 Rn(4) Rd(4) 1 1 1 1 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/shasx_A88171.d b/src/arch/arm/v7/opdefs/shasx_A88171.d new file mode 100644 index 0000000..71d241b --- /dev/null +++ b/src/arch/arm/v7/opdefs/shasx_A88171.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SHASX + +@desc Signed Halving Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one signed 16-bit integer addition and one signed 16-bit subtraction, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 0 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 1 Rn(4) Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/shsax_A88172.d b/src/arch/arm/v7/opdefs/shsax_A88172.d new file mode 100644 index 0000000..8794738 --- /dev/null +++ b/src/arch/arm/v7/opdefs/shsax_A88172.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SHSAX + +@desc Signed Halving Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one signed 16-bit integer subtraction and one signed 16-bit addition, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 1 0 Rn(4) 1 1 1 1 Rd(4) 0 0 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 1 Rn(4) Rd(4) 1 1 1 1 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/shsub16_A88173.d b/src/arch/arm/v7/opdefs/shsub16_A88173.d new file mode 100644 index 0000000..f7099f2 --- /dev/null +++ b/src/arch/arm/v7/opdefs/shsub16_A88173.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SHSUB16 + +@desc Signed Halving Subtract 16 performs two signed 16-bit integer subtractions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 1 Rn(4) 1 1 1 1 Rd(4) 0 0 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 1 Rn(4) Rd(4) 1 1 1 1 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/shsub8_A88174.d b/src/arch/arm/v7/opdefs/shsub8_A88174.d new file mode 100644 index 0000000..99af65d --- /dev/null +++ b/src/arch/arm/v7/opdefs/shsub8_A88174.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SHSUB8 + +@desc Signed Halving Subtract 8 performs four signed 8-bit integer subtractions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 0 Rn(4) 1 1 1 1 Rd(4) 0 0 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 0 1 1 Rn(4) Rd(4) 1 1 1 1 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smlad_A88177.d b/src/arch/arm/v7/opdefs/smlad_A88177.d new file mode 100644 index 0000000..3eabaa9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smlad_A88177.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMLAD + +@desc Signed Multiply Accumulate Dual performs two signed 16 × 16-bit multiplications. It adds the products to a 32-bit accumulate operand. Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This produces top × bottom and bottom × top multiplication. This instruction sets the Q flag if the accumulate operation overflows. Overflow cannot occur during the multiplications. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 0 1 0 Rn(4) Ra(4) Rd(4) 0 0 0 M(1) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 0 0 0 Rd(4) Ra(4) Rm(4) 0 0 M(1) 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smlal_A88178.d b/src/arch/arm/v7/opdefs/smlal_A88178.d index a3a36aa..03da53c 100644 --- a/src/arch/arm/v7/opdefs/smlal_A88178.d +++ b/src/arch/arm/v7/opdefs/smlal_A88178.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,52 +23,47 @@ @title SMLAL -@encoding(T1) { +@desc Signed Multiply Accumulate Long multiplies two signed 32-bit values to produce a 64-bit value, and accumulates this with a 64-bit value. In ARM instructions, the condition flags can optionally be updated based on the result. Use of this option adversely affects performance on many processor implementations. - @word 1 1 1 1 1 0 1 1 1 1 0 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) +@encoding (T1) { - @syntax <RdLo> <RdHi> <Rn> <Rm> + @word 1 1 1 1 1 0 1 1 1 1 0 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) - @conv { + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) - @rules { - - //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 1 1 1 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 1 1 1 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') - } + } - @rules { + @rules { - //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/smlald_A88180.d b/src/arch/arm/v7/opdefs/smlald_A88180.d new file mode 100644 index 0000000..fa6a473 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smlald_A88180.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMLALD + +@desc Signed Multiply Accumulate Long Dual performs two signed 16 × 16-bit multiplications. It adds the products to a 64-bit accumulate operand. Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This produces top × bottom and bottom × top multiplication. Overflow is possible during this instruction, but only as a result of the 64-bit addition. This overflow is not detected if it occurs. Instead, the result wraps around modulo 264. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 1 1 0 0 Rn(4) RdLo(4) RdHi(4) 1 1 0 M(1) Rm(4) + + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> + + @conv { + + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 1 0 0 RdHi(4) RdLo(4) Rm(4) 0 0 M(1) 1 Rn(4) + + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> + + @conv { + + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smlsd_A88182.d b/src/arch/arm/v7/opdefs/smlsd_A88182.d new file mode 100644 index 0000000..d458fa8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smlsd_A88182.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMLSD + +@desc Signed Multiply Subtract Dual performs two signed 16 × 16-bit multiplications. It adds the difference of the products to a 32-bit accumulate operand. Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This produces top × bottom and bottom × top multiplication. This instruction sets the Q flag if the accumulate operation overflows. Overflow cannot occur during the multiplications or subtraction. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 1 0 0 Rn(4) Ra(4) Rd(4) 0 0 0 M(1) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 0 0 0 Rd(4) Ra(4) Rm(4) 0 1 M(1) 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smlsld_A88183.d b/src/arch/arm/v7/opdefs/smlsld_A88183.d new file mode 100644 index 0000000..9f64eed --- /dev/null +++ b/src/arch/arm/v7/opdefs/smlsld_A88183.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMLSLD + +@desc Signed Multiply Subtract Long Dual performs two signed 16 × 16-bit multiplications. It adds the difference of the products to a 64-bit accumulate operand. Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This produces top × bottom and bottom × top multiplication. Overflow is possible during this instruction, but only as a result of the 64-bit addition. This overflow is not detected if it occurs. Instead, the result wraps around modulo 264. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 1 1 0 1 Rn(4) RdLo(4) RdHi(4) 1 1 0 M(1) Rm(4) + + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> + + @conv { + + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 1 0 0 RdHi(4) RdLo(4) Rm(4) 0 1 M(1) 1 Rn(4) + + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> + + @conv { + + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smmla_A88184.d b/src/arch/arm/v7/opdefs/smmla_A88184.d new file mode 100644 index 0000000..a4d29b8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smmla_A88184.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMMLA + +@desc Signed Most Significant Word Multiply Accumulate multiplies two signed 32-bit values, extracts the most significant 32 bits of the result, and adds an accumulate value. Optionally, the instruction can specify that the result is rounded instead of being truncated. In this case, the constant 0x80000000 is added to the product before the high word is extracted. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 1 0 1 Rn(4) Ra(4) Rd(4) 0 0 0 R(1) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + round = (R == '1') + + } + + @rules { + + if (round); chk_call ExtendKeyword("r") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 1 0 1 Rd(4) Ra(4) Rm(4) 0 0 R(1) 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + round = (R == '1') + + } + + @rules { + + if (round); chk_call ExtendKeyword("r") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smmls_A88185.d b/src/arch/arm/v7/opdefs/smmls_A88185.d new file mode 100644 index 0000000..d59617b --- /dev/null +++ b/src/arch/arm/v7/opdefs/smmls_A88185.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMMLS + +@desc Signed Most Significant Word Multiply Subtract multiplies two signed 32-bit values, subtracts the result from a 32-bit accumulate value that is shifted left by 32 bits, and extracts the most significant 32 bits of the result of that subtraction. Optionally, the instruction can specify that the result of the instruction is rounded instead of being truncated. In this case, the constant 0x80000000 is added to the result of the subtraction before the high word is extracted. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 1 1 0 Rn(4) Ra(4) Rd(4) 0 0 0 R(1) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + round = (R == '1') + + } + + @rules { + + if (round); chk_call ExtendKeyword("r") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 1 0 1 Rd(4) Ra(4) Rm(4) 1 1 R(1) 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + round = (R == '1') + + } + + @rules { + + if (round); chk_call ExtendKeyword("r") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smmul_A88186.d b/src/arch/arm/v7/opdefs/smmul_A88186.d new file mode 100644 index 0000000..e02ca52 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smmul_A88186.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMMUL + +@desc Signed Most Significant Word Multiply multiplies two signed 32-bit values, extracts the most significant 32 bits of the result, and writes those bits to the destination register. Optionally, the instruction can specify that the result is rounded instead of being truncated. In this case, the constant 0x80000000 is added to the product before the high word is extracted. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 1 0 1 Rn(4) 1 1 1 1 Rd(4) 0 0 0 R(1) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + round = (R == '1') + + } + + @rules { + + if (round); chk_call ExtendKeyword("r") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 1 0 1 Rd(4) 1 1 1 1 Rm(4) 0 0 R(1) 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + round = (R == '1') + + } + + @rules { + + if (round); chk_call ExtendKeyword("r") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smuad_A88187.d b/src/arch/arm/v7/opdefs/smuad_A88187.d new file mode 100644 index 0000000..324e257 --- /dev/null +++ b/src/arch/arm/v7/opdefs/smuad_A88187.d @@ -0,0 +1,74 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SMUAD + +@desc Signed Dual Multiply Add performs two signed 16 × 16-bit multiplications. It adds the products together, and writes the result to the destination register. Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This produces top × bottom and bottom × top multiplication. This instruction sets the Q flag if the addition overflows. The multiplications cannot overflow. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 0 0 M(1) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 0 0 0 Rd(4) 1 1 1 1 Rm(4) 0 0 M(1) 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + m_swap = (M == '1') + + } + + @rules { + + if (m_swap); chk_call ExtendKeyword("x") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/smull_A88189.d b/src/arch/arm/v7/opdefs/smull_A88189.d index 15fc195..5ab1c54 100644 --- a/src/arch/arm/v7/opdefs/smull_A88189.d +++ b/src/arch/arm/v7/opdefs/smull_A88189.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,52 +23,47 @@ @title SMULL -@encoding(T1) { +@desc Signed Multiply Long multiplies two 32-bit signed values to produce a 64-bit result. In ARM instructions, the condition flags can optionally be updated based on the result. Use of this option adversely affects performance on many processor implementations. - @word 1 1 1 1 1 0 1 1 1 0 0 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) +@encoding (T1) { - @syntax <RdLo> <RdHi> <Rn> <Rm> + @word 1 1 1 1 1 0 1 1 1 0 0 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) - @conv { + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) - @rules { - - //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 1 1 0 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 1 1 0 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') - } + } - @rules { + @rules { - //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/str_A88203.d b/src/arch/arm/v7/opdefs/str_A88203.d index 2952e1a..e3feaf7 100644 --- a/src/arch/arm/v7/opdefs/str_A88203.d +++ b/src/arch/arm/v7/opdefs/str_A88203.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,113 +23,76 @@ @title STR (immediate, Thumb) -@encoding(t1) { +@desc Store Register (immediate) calculates an address from a base register value and an immediate offset, and stores a word from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 1 0 0 imm5(5) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt> <access> + @half 0 1 1 0 0 imm5(5) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm5:'00', 7, 32); - access = MakeMemoryAccess(Rgn, imm32, 1, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm5:'00', 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) -} - -@encoding(t2) { - - @half 1 0 0 1 0 Rt(3) imm8(8) - - @syntax <Rgt> <access> - - @conv { - - Rgt = Register(Rt) - Sp = Register(13) - imm32 = ZeroExtend(imm8:'00', 10, 32); - access = MakeMemoryAccess(Sp, imm32, 1, 0) - - } + } } -@encoding(T3) { - - @word 1 1 1 1 1 0 0 0 1 1 0 0 Rn(4) Rt(4) imm12(12) - - @syntax "str.W" <Rgt> <access> +@encoding (t2) { - @conv { + @half 1 0 0 1 0 Rt(3) imm8(8) - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - access = MakeMemoryAccess(Rgn, imm32, 1, 0) + @syntax <reg_T> <mem_access> - } + @conv { - @rules { + reg_T = Register(Rt) + imm32 = ZeroExtend(imm8:'00', 32) + SP = Register(13) + mem_access = MakeMemoryAccess(SP, imm32, NULL, true, true, false) - //if Rn == '1111' then UNDEFINED; - //if t == 15 then UNPREDICTABLE; - - } + } } -@encoding(T41) { - - @word 1 1 1 1 1 0 0 0 0 1 0 0 Rn(4) Rt(4) 1 1 U(1) W(1) imm8(8) - - @syntax <Rgt> <access> - - @conv { +@encoding (T3) { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - access = MakeMemoryAccess(Rgn, imm32, U, W) + @word 1 1 1 1 1 0 0 0 1 1 0 0 Rn(4) Rt(4) imm12(12) - } + @syntax ".W" <reg_T> <mem_access> - @rules { + @conv { - //if P == '1' && U == '1' && W == '0' then SEE STRT; - //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; - //if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - //if t == 15 || (wback && n == t) then UNPREDICTABLE; + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) - } + } } -@encoding(T42) { +@encoding (T4) { - @word 1 1 1 1 1 0 0 0 0 1 0 0 Rn(4) Rt(4) 1 0 U(1) W(1) imm8(8) + @word 1 1 1 1 1 0 0 0 0 1 0 0 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) - @syntax <Rgt> <base> <offset> + @syntax <reg_T> <mem_access> - @conv { + @conv { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - } - - @rules { - - //if P == '1' && U == '1' && W == '0' then SEE STRT; - //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm8 == '00000100' then SEE PUSH; - //if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - //if t == 15 || (wback && n == t) then UNPREDICTABLE; - - } + } } + diff --git a/src/arch/arm/v7/opdefs/str_A88204.d b/src/arch/arm/v7/opdefs/str_A88204.d index fb5879a..d780ae3 100644 --- a/src/arch/arm/v7/opdefs/str_A88204.d +++ b/src/arch/arm/v7/opdefs/str_A88204.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,55 +23,31 @@ @title STR (immediate, ARM) -@encoding(A11) { +@desc Store Register (immediate) calculates an address from a base register value and an immediate offset, and stores a word from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @word cond(4) 0 1 0 1 U(1) 0 W(1) 0 Rn(4) Rt(4) imm12(12) +@encoding (A1) { - @syntax <Rgt> <access> + @word cond(4) 0 1 0 P(1) U(1) 0 W(1) 0 Rn(4) Rt(4) imm12(12) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - access = MakeMemoryAccess(Rgn, imm32, U, 1) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - @rules { + } - //if P == '0' && W == '1' then SEE STRT; - //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; - //if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + @rules { - } + chk_call StoreCondition(cond) -} - -@encoding(A12) { - - @word cond(4) 0 1 0 0 U(1) 0 W(1) 0 Rn(4) Rt(4) imm12(12) - - @syntax <Rgt> <base> <offset> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) - - } - - @rules { - - //if P == '0' && W == '1' then SEE STRT; - //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; - //if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/str_A88205.d b/src/arch/arm/v7/opdefs/str_A88205.d new file mode 100644 index 0000000..55f154c --- /dev/null +++ b/src/arch/arm/v7/opdefs/str_A88205.d @@ -0,0 +1,89 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title STR (register) + +@desc Store Register (register) calculates an address from a base register value and an offset register value, stores a word from a register to memory. The offset register value can optionally be shifted. For information about memory accesses see Memory accesses on page A8-294. + +@encoding (t1) { + + @half 0 1 0 1 0 0 0 Rm(3) Rn(3) Rt(3) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, true, false) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 0 0 0 1 0 0 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) + + @syntax ".W" <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, true, false) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 P(1) U(1) 0 W(1) 0 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + + @syntax <reg_T> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + shift = DecodeImmShift(type, imm5) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, index, add, wback) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/strb_A88206.d b/src/arch/arm/v7/opdefs/strb_A88206.d index 4799f61..2caf94c 100644 --- a/src/arch/arm/v7/opdefs/strb_A88206.d +++ b/src/arch/arm/v7/opdefs/strb_A88206.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,94 +23,59 @@ @title STRB (immediate, Thumb) -@encoding(t1) { +@desc Store Register Byte (immediate) calculates an address from a base register value and an immediate offset, and stores a byte from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 1 1 0 imm5(5) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt>, <access> + @half 0 1 1 1 0 imm5(5) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm5, 5, 32) - access = MakeMemoryAccess(Rgn, imm32, 1, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm5, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) -} - -@encoding(T2) { - - @word 1 1 1 1 1 0 0 0 1 0 0 0 Rn(4) Rt(4) imm12(12) - - @syntax "strb.W" <Rgt>, <access> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32) - access = MakeMemoryAccess(Rgn, imm32, 1, 0) - - } - - @rules { - - //if Rn == '1111' then UNDEFINED; - //if t IN {13,15} then UNPREDICTABLE; - - } + } } -@encoding(T31) { - - @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 1 1 U(1) W(1) imm8(8) - - @syntax <Rgt> <access> - - @conv { +@encoding (T2) { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - access = MakeMemoryAccess(Rgn, imm32, U, W) + @word 1 1 1 1 1 0 0 0 1 0 0 0 Rn(4) Rt(4) imm12(12) - } + @syntax ".W" <reg_T> <mem_access> - @rules { + @conv { - //if P == '1' && U == '1' && W == '0' then SEE STRBT; - //if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - //if t IN {13,15} || (wback && n == t) then UNPREDICTABLE; + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, true, true, false) - } + } } -@encoding(T32) { +@encoding (T3) { - @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 1 0 U(1) W(1) imm8(8) + @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 1 P(1) U(1) W(1) imm8(8) - @syntax <Rgt> <base> <offset> + @syntax <reg_T> <mem_access> - @conv { + @conv { - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm8, 8, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm8, 32) + index = (P == '1') + add = (U == '1') + wback = (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - } - - @rules { - - //if P == '1' && U == '1' && W == '0' then SEE STRBT; - //if Rn == '1111' || (P == '0' && W == '0') then UNDEFINED; - //if t IN {13,15} || (wback && n == t) then UNPREDICTABLE; - - } + } } + diff --git a/src/arch/arm/v7/opdefs/strb_A88207.d b/src/arch/arm/v7/opdefs/strb_A88207.d index 2af8fb7..4e893fb 100644 --- a/src/arch/arm/v7/opdefs/strb_A88207.d +++ b/src/arch/arm/v7/opdefs/strb_A88207.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,59 +23,31 @@ @title STRB (immediate, ARM) -@encoding(A11) { +@desc Store Register Byte (immediate) calculates an address from a base register value and an immediate offset, and stores a byte from a register to memory. It can use offset, post-indexed, or pre-indexed addressing. For information about memory accesses see Memory accesses on page A8-294. - @word cond(4) 0 1 0 1 U(1) 1 W(1) 0 Rn(4) Rt(4) imm12(12) +@encoding (A1) { - @syntax <Rgt> <access> + @word cond(4) 0 1 0 P(1) U(1) 1 W(1) 0 Rn(4) Rt(4) imm12(12) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - access = MakeMemoryAccess(Rgn, imm32, U, W) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm12, 32) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + mem_access = MakeMemoryAccess(reg_N, imm32, NULL, index, add, wback) - @rules { + } - //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); - //if Rn == '1111' then SEE LDRB (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRBT; - //if P == '0' && W == '0' then UNDEFINED; - //if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + @rules { - } + chk_call StoreCondition(cond) -} - -@encoding(A12) { - - @word cond(4) 0 1 0 0 U(1) 1 W(1) 0 Rn(4) Rt(4) imm12(12) - - @syntax <Rgt> <base> <offset> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - imm32 = ZeroExtend(imm12, 12, 32); - base = MakeMemoryNotIndexed(Rgn, W) - offset = MakeAccessOffset(U, imm32) - - } - - @rules { - - //if Rt == '1111' && P == '1' && U == '0' && W == '0' then SEE PLD, PLDW (immediate); - //if Rn == '1111' then SEE LDRB (literal); - //if P == '1' && U == '1' && W == '0' then SEE LDRBT; - //if P == '0' && W == '0' then UNDEFINED; - //if t == 13 || (t == 15 && W == '1') || (wback && n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } + diff --git a/src/arch/arm/v7/opdefs/strb_A88208.d b/src/arch/arm/v7/opdefs/strb_A88208.d index c94fe4d..36f6134 100644 --- a/src/arch/arm/v7/opdefs/strb_A88208.d +++ b/src/arch/arm/v7/opdefs/strb_A88208.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,105 +23,67 @@ @title STRB (register) -@encoding(t1) { +@desc Store Register Byte (register) calculates an address from a base register value and an offset register value, and stores a byte from a register to memory. The offset register value can optionally be shifted. For information about memory accesses see Memory accesses on page A8-294. - @half 0 1 0 1 0 1 0 Rm(3) Rn(3) Rt(3) +@encoding (t1) { - @syntax <Rgt> <access> + @half 0 1 0 1 0 1 0 Rm(3) Rn(3) Rt(3) - @conv { + @syntax <reg_T> <mem_access> - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - access = _MakeMemoryAccess(Rgn, Rgm, 0) + @conv { - } + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + mem_access = MakeMemoryAccess(reg_N, reg_M, NULL, true, true, false) - @rules { - - } + } } -@encoding(T2) { - - @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) - - @syntax "strb.W" <Rgt>, <access> - - @conv { +@encoding (T2) { - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - shift = DecodeImmShift(0, imm2) - access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, 0) + @word 1 1 1 1 1 0 0 0 0 0 0 0 Rn(4) Rt(4) 0 0 0 0 0 0 imm2(2) Rm(4) - } + @syntax ".W" <reg_T> <mem_access> - @rules { + @conv { - //if Rn == '1111' then UNDEFINED; - //if t IN {13,15} || m IN {13,15} then UNPREDICTABLE; + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(0, imm2) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, true, true, false) - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } + } } -@encoding(A11) { +@encoding (A1) { - @word cond(4) 0 1 1 1 U(1) 1 W(1) 0 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 1 1 P(1) U(1) 1 W(1) 0 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) - @syntax <Rgt> <access> + @syntax <reg_T> <mem_access> - @conv { + @conv { - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - shift = DecodeImmShift(type, imm5) - access = MakeShiftedMemoryAccess(Rgn, Rgm, shift, W) + reg_T = Register(Rt) + reg_N = Register(Rn) + reg_M = Register(Rm) + index = (P == '1') + add = (U == '1') + wback = (P == '0') || (W == '1') + shift = DecodeImmShift(type, imm5) + mem_access = MakeMemoryAccess(reg_N, reg_M, shift, index, add, wback) - } + } - @rules { + @rules { - //if P == '0' && W == '1' then SEE STRT; - //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; - //if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) + chk_call StoreCondition(cond) - } + } } -@encoding(A12) { - - @word cond(4) 0 1 1 0 U(1) 1 W(1) 0 Rn(4) Rt(4) imm5(5) type(2) 0 Rm(4) - - @syntax <Rgt> <base> <offset> <?shift> - - @conv { - - Rgt = Register(Rt) - Rgn = Register(Rn) - Rgm = Register(Rm) - base = MakeMemoryNotIndexed(Rgn, 1) - offset = MakeAccessOffset(U, Rgm) - shift = DecodeImmShift(type, imm5) - - } - - @rules { - - //if P == '0' && W == '1' then SEE STRT; - //if Rn == '1101' && P == '1' && U == '0' && W == '1' && imm12 == '000000000100' then SEE PUSH; - //if wback && (n == 15 || n == t) then UNPREDICTABLE; - if (Rt == '1111'); chk_call SetInsFlag(AIF_RETURN_POINT) - - } - -} diff --git a/src/arch/arm/v7/opdefs/sub_A88221.d b/src/arch/arm/v7/opdefs/sub_A88221.d index ec6f241..41ce6b3 100644 --- a/src/arch/arm/v7/opdefs/sub_A88221.d +++ b/src/arch/arm/v7/opdefs/sub_A88221.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,94 +23,76 @@ @title SUB (immediate, Thumb) -@encoding(t1) { +@desc This instruction subtracts an immediate value from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 1 1 1 1 imm3(3) Rn(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rn> <const> + @half 0 0 0 1 1 1 1 imm3(3) Rn(3) Rd(3) - @conv { + @syntax "subs" <reg_D> <reg_N> <imm32> - Rd = Register(Rd) - Rn = Register(Rn) - const = ZeroExtend(imm3, 3, 32); + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + imm32 = ZeroExtend(imm3, 32) - @rules { - - //setflags = !InITBlock(); - - } + } } -@encoding(t2) { - - @half 0 0 1 1 1 Rdn(3) imm8(8) - - @syntax <Rdn> <const> - - @conv { +@encoding (t2) { - Rdn = Register(Rdn) - const = ZeroExtend(imm8, 8, 32); + @half 0 0 1 1 1 Rdn(3) imm8(8) - } + @syntax "subs" <reg_DN> <imm32> - @rules { + @conv { - //setflags = !InITBlock(); + reg_DN = Register(Rdn) + imm32 = ZeroExtend(imm8, 32) - } + } } -@encoding(T3) { +@encoding (T3) { - @word 1 1 1 1 0 i(1) 0 1 1 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 0 1 1 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm8(8) - @syntax {S} ".W" <Rd> <Rn> <const> + @syntax <reg_D> <reg_N> <imm32> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, i) + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE CMP (immediate); - //if Rn == '1101' then SEE SUB (SP minus immediate); - //if d == 13 || (d == 15 && S == '0') || n == 15 then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(T4) { +@encoding (T4) { - @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 Rn(4) 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 Rn(4) 0 imm3(3) Rd(4) imm8(8) - @syntax "subw" <Rd> <Rn> <const> + @syntax "subw" <reg_D> <reg_N> <imm32> - @conv { + @conv { - Rd = Register(Rd) - Rn = Register(Rn) - const = ZeroExtend(i:imm3:imm8, 12, 32) + reg_D = Register(Rd) + reg_N = Register(Rn) + imm32 = ZeroExtend(i:imm3:imm8, 32) - } - - @rules { - - //if Rn == '1111' then SEE ADR; - //if Rn == '1101' then SEE SUB (SP minus immediate); - //if d IN {13,15} then UNPREDICTABLE; - - } + } } + diff --git a/src/arch/arm/v7/opdefs/sub_A88222.d b/src/arch/arm/v7/opdefs/sub_A88222.d index 5564a07..ef326b8 100644 --- a/src/arch/arm/v7/opdefs/sub_A88222.d +++ b/src/arch/arm/v7/opdefs/sub_A88222.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,29 +23,29 @@ @title SUB (immediate, ARM) -@encoding(A1) { +@desc This instruction subtracts an immediate value from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @word cond(4) 0 0 1 0 0 1 0 S(1) Rn(4) Rd(4) imm12(12) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rn> <const> + @word cond(4) 0 0 1 0 0 1 0 S(1) Rn(4) Rd(4) imm12(12) - @conv { + @syntax <reg_D> <reg_N> <imm32> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - const = ARMExpandImm(imm12) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) - @rules { + } - //if ((Rn == '1111') && (S == '0')) ; see ADR - //if (Rn == '1101') ; see SUB (SP minus immediate) - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + @rules { + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/sub_A88223.d b/src/arch/arm/v7/opdefs/sub_A88223.d index 3693bc4..a629250 100644 --- a/src/arch/arm/v7/opdefs/sub_A88223.d +++ b/src/arch/arm/v7/opdefs/sub_A88223.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,71 +23,71 @@ @title SUB (register) -@encoding(t1) { +@desc This instruction subtracts an optionally-shifted register value from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. - @half 0 0 0 1 1 0 1 Rm(3) Rn(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rn> <Rm> + @half 0 0 0 1 1 0 1 Rm(3) Rn(3) Rd(3) - @conv { + @syntax "subs" <reg_D> <reg_N> <reg_M> - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 0 1 0 1 1 1 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + @word 1 1 1 0 1 0 1 1 1 0 1 S(1) Rn(4) 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) - @syntax {S} <Rd> <Rn> <Rm> <?shift> + @syntax <reg_D> <reg_N> <reg_M> <?shift> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) - } + } - @rules { - - //if ((Rd == '1111') && (S == '1')) ; see CMP (register) - //if (Rn == '1101') ; see SUB (SP minus register) - //if ((d == 13) || ((d == 15) && (S == '0')) [[ n == 15 || (m IN {13,15})) ; unpredictable + @rules { - } + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") -} + } -@encoding(A1) { +} - @word cond(4) 0 0 0 0 0 1 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) +@encoding (A1) { - @syntax {S} {c} <Rd> <Rn> <Rm> <?shift> + @word cond(4) 0 0 0 0 0 1 0 S(1) Rn(4) Rd(4) imm5(5) type(2) 0 Rm(4) - @conv { + @syntax <reg_D> <reg_N> <reg_M> <?shift> - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + @conv { - } + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) - @rules { + } - //if (Rn == '1101') ; see SUB (SP minus register) - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + @rules { + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/sub_A88224.d b/src/arch/arm/v7/opdefs/sub_A88224.d new file mode 100644 index 0000000..5ef4e4d --- /dev/null +++ b/src/arch/arm/v7/opdefs/sub_A88224.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SUB (register-shifted register) + +@desc This instruction subtracts a register-shifted register value from a register value, and writes the result to the destination register. It can optionally update the condition flags based on the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 0 0 1 0 S(1) Rn(4) Rd(4) Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/sub_A88225.d b/src/arch/arm/v7/opdefs/sub_A88225.d index e37997f..dc54c6b 100644 --- a/src/arch/arm/v7/opdefs/sub_A88225.d +++ b/src/arch/arm/v7/opdefs/sub_A88225.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,94 +23,85 @@ @title SUB (SP minus immediate) -@encoding(t1) { +@desc This instruction subtracts an immediate value from the SP value, and writes the result to the destination register. - @half 1 0 1 1 0 0 0 0 1 imm7(7) +@encoding (t1) { - @syntax <SP1> <SP2> <const> + @half 1 0 1 1 0 0 0 0 1 imm7(7) - @conv { + @syntax <SP_0> <SP_1> <imm32> - SP1 = Register(13) - SP2 = Register(13) - const = ZeroExtend(imm7:'00', 9, 32); + @conv { - } + imm32 = ZeroExtend(imm7:'00', 32) + SP_0 = Register(13) + SP_1 = Register(13) - @rules { - - //setflags = FALSE - - } + } } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 i(1) 0 1 1 0 1 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) + @word 1 1 1 1 0 i(1) 0 1 1 0 1 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm8(8) - @syntax {S} ".W" <Rd> <SP> <const> + @syntax <reg_D> <SP> <imm32> - @conv { + @conv { - S = SetFlags(S) - Rd = Register(Rd) - SP = Register(13) - const = ThumbExpandImm(i:imm3:imm8) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ThumbExpandImm(i:imm3:imm8) + SP = Register(13) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE CMP (immediate); - //if d == 15 && S == '0' then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call ExtendKeyword(".w") - } + } } -@encoding(T3) { - - @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 1 1 0 1 0 imm3(3) Rd(4) imm8(8) +@encoding (T3) { - @syntax "subw" <Rd> <SP> <const> + @word 1 1 1 1 0 i(1) 1 0 1 0 1 0 1 1 0 1 0 imm3(3) Rd(4) imm8(8) - @conv { + @syntax "subw" <reg_D> <SP> <imm32> - Rd = Register(Rd) - SP = Register(13) - const = ZeroExtend(i:imm3:imm8, 12, 32) + @conv { - } + reg_D = Register(Rd) + imm32 = ZeroExtend(i:imm3:imm8, 32) + SP = Register(13) - @rules { - - //if d == 15 then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 1 0 0 1 0 S(1) 1 1 0 1 Rd(4) imm12(12) + @word cond(4) 0 0 1 0 0 1 0 S(1) 1 1 0 1 Rd(4) imm12(12) - @syntax {S} {c} <Rd> <SP> <const> + @syntax <reg_D> <SP> <imm32> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - Rd = Register(Rd) - SP = Register(13) - const = ARMExpandImm(imm12) + reg_D = Register(Rd) + setflags = (S == '1') + imm32 = ARMExpandImm(imm12) + SP = Register(13) - } + } - @rules { + @rules { - //if Rd == '1111' && S == '1' then SEE SUBS PC, LR and related instructions; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/sub_A88226.d b/src/arch/arm/v7/opdefs/sub_A88226.d new file mode 100644 index 0000000..02ecada --- /dev/null +++ b/src/arch/arm/v7/opdefs/sub_A88226.d @@ -0,0 +1,76 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SUB (SP minus register) + +@desc This instruction subtracts an optionally-shifted register value from the SP value, and writes the result to the destination register. + +@encoding (T1) { + + @word 1 1 1 0 1 0 1 1 1 0 1 S(1) 1 1 0 1 0 imm3(3) Rd(4) imm2(2) type(2) Rm(4) + + @syntax <reg_D> <SP> <reg_M> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm3:imm2) + SP = Register(13) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + + } + +} + +@encoding (A1) { + + @word cond(4) 0 0 0 0 0 1 0 S(1) 1 1 0 1 Rd(4) imm5(5) type(2) 0 Rm(4) + + @syntax <reg_D> <SP> <reg_M> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + setflags = (S == '1') + shift = DecodeImmShift(type, imm5) + SP = Register(13) + + } + + @rules { + + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/svc_A88228.d b/src/arch/arm/v7/opdefs/svc_A88228.d new file mode 100644 index 0000000..be48545 --- /dev/null +++ b/src/arch/arm/v7/opdefs/svc_A88228.d @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SVC (previously SWI) + +@desc Supervisor Call, previously called Software Interrupt, causes a Supervisor Call exception. For more information, see Supervisor Call (SVC) exception on page B1-1209. Software can use this instruction as a call to an operating system to provide a service. In the following cases, the Supervisor Call exception generated by the SVC instruction is taken to Hyp mode: • If the SVC is executed in Hyp mode. • If HCR.TGE is set to 1, and the SVC is executed in Non-secure User mode. For more information, see Supervisor Call exception, when HCR.TGE is set to 1 on page B1-1191 In these cases, the HSR identifies that the exception entry was caused by a Supervisor Call exception, EC value 0x11, see Use of the HSR on page B3-1424. The immediate field in the HSR: • if the SVC is unconditional: — for the Thumb instruction, is the zero-extended value of the imm8 field — for the ARM instruction, is the least-significant 16 bits the imm24 field • if the SVC is conditional, is UNKNOWN. + +@encoding (t1) { + + @half 1 1 0 1 1 1 1 1 imm8(8) + + @syntax <imm32> + + @conv { + + imm32 = ZeroExtend(imm8, 32) + + } + +} + +@encoding (A1) { + + @word cond(4) 1 1 1 1 imm24(24) + + @syntax <imm32> + + @conv { + + imm32 = ZeroExtend(imm24, 32) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/swp_A88229.d b/src/arch/arm/v7/opdefs/swp_A88229.d new file mode 100644 index 0000000..2e39015 --- /dev/null +++ b/src/arch/arm/v7/opdefs/swp_A88229.d @@ -0,0 +1,52 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title SWP, SWPB + +@desc SWP (Swap) swaps a word between registers and memory. SWP loads a word from the memory address given by the value of register <Rn>. The value of register <Rt2> is then stored to the memory address given by the value of <Rn>, and the original loaded value is written to register <Rt>. If the same register is specified for <Rt> and <Rt2>, this instruction swaps the value of the register and the value at the memory address. SWPB (Swap Byte) swaps a byte between registers and memory. SWPB loads a byte from the memory address given by the value of register <Rn>. The value of the least significant byte of register <Rt2> is stored to the memory address given by <Rn>, the original loaded value is zero-extended to a 32-bit word, and the word is written to register <Rt>. If the same register is specified for <Rt> and <Rt2>, this instruction swaps the value of the least significant byte of the register and the byte value at the memory address, and clears the most significant three bytes of the register. For both instructions, the memory system ensures that no other memory access can occur to the memory location between the load access and the store access. Note • The SWP and SWPB instructions rely on the properties of the system beyond the processor to ensure that no stores from other observers can occur between the load access and the store access, and this might not be implemented for all regions of memory on some system implementations. In all cases, SWP and SWPB do ensure that no stores from the processor that executed the SWP or SWPB instruction can occur between the load access and the store access of the SWP or SWPB. • ARM deprecates the use of SWP and SWPB, and strongly recommends that new software uses: LDREX/STREX in preference to SWP — LDREXB/STREXB in preference to SWPB. — • If the translation table entries that relate to a memory location accessed by the SWP or SWPB instruction change, or are seen to change by the executing processor as a result of TLB eviction, this might mean that the translation table attributes, permissions or addresses for the load are different to those for the store. In this case, the architecture makes no guarantee that no memory access occur to these memory locations between the load and store. The Virtualization Extensions make the SWP and SWPB instructions OPTIONAL and deprecated: • If an implementation does not include the SWP and SWPB instructions, the ID_ISAR0.Swap_instrs and ID_ISAR4.SWP_frac fields are zero, see About the Instruction Set Attribute registers on page B7-1950. • In an implementation that includes SWP and SWPB, both instructions are UNDEFINED in Hyp mode. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 B(1) 0 0 Rn(4) Rt(4) 0 0 0 0 1 0 0 1 Rt2(4) + + @syntax <reg_T> <reg_T2> <mem_access> + + @conv { + + reg_T = Register(Rt) + reg_T2 = Register(Rt2) + reg_N = Register(Rn) + size = (B != 4) + mem_access = MakeMemoryAccess(reg_N, NULL, NULL, true, false, false) + + } + + @rules { + + if (size); chk_call ExtendKeyword("b") + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/teq_A88237.d b/src/arch/arm/v7/opdefs/teq_A88237.d index 96ac2cb..89073f6 100644 --- a/src/arch/arm/v7/opdefs/teq_A88237.d +++ b/src/arch/arm/v7/opdefs/teq_A88237.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,39 +23,41 @@ @title TEQ (immediate) -@encoding(T1) { +@desc Test Equivalence (immediate) performs a bitwise exclusive OR operation on a register value and an immediate value. It updates the condition flags based on the result, and discards the result. - @word 1 1 1 1 0 i(1) 0 0 1 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) +@encoding (T1) { - @syntax <Rn> <const> + @word 1 1 1 1 0 i(1) 0 0 1 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) - @conv { + @syntax <reg_N> <imm32> - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_N = Register(Rn) + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - //if (n IN {13,15}) ; unpredictable +} - } +@encoding (A1) { -} + @word cond(4) 0 0 1 1 0 0 1 1 Rn(4) 0 0 0 0 imm12(12) -@encoding(A1) { + @syntax <reg_N> <imm32> - @word cond(4) 0 0 1 1 0 0 1 1 Rn(4) 0 0 0 0 imm12(12) + @conv { - @syntax {c} <Rn> <const> + reg_N = Register(Rn) + imm32 = ARMExpandImm_C(imm12, 0) - @conv { + } - c = Condition(cond) - Rn = Register(Rn) - const = ARMExpandImm_C(imm12, 0) + @rules { - } + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/teq_A88238.d b/src/arch/arm/v7/opdefs/teq_A88238.d index a79eb3e..8187d81 100644 --- a/src/arch/arm/v7/opdefs/teq_A88238.d +++ b/src/arch/arm/v7/opdefs/teq_A88238.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,41 +23,43 @@ @title TEQ (register) -@encoding(T1) { +@desc Test Equivalence (register) performs a bitwise exclusive OR operation on a register value and an optionally-shifted register value. It updates the condition flags based on the result, and discards the result. - @word 1 1 1 0 1 0 1 0 1 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) +@encoding (T1) { - @syntax <Rn> <Rm> <?shift> + @word 1 1 1 0 1 0 1 0 1 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) - @conv { + @syntax <reg_N> <reg_M> <?shift> - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + @conv { - } + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm3:imm2) - @rules { + } - //if n IN {13,15} || m IN {13,15} then UNPREDICTABLE +} - } +@encoding (A1) { -} + @word cond(4) 0 0 0 1 0 0 1 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) -@encoding(A1) { + @syntax <reg_N> <reg_M> <?shift> - @word cond(4) 0 0 0 1 0 0 1 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) + @conv { - @syntax {c} <Rn> <Rm> <?shift> + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm5) - @conv { + } - c = Condition(cond) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + @rules { - } + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/teq_A88239.d b/src/arch/arm/v7/opdefs/teq_A88239.d new file mode 100644 index 0000000..986a7f0 --- /dev/null +++ b/src/arch/arm/v7/opdefs/teq_A88239.d @@ -0,0 +1,49 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title TEQ (register-shifted register) + +@desc Test Equivalence (register-shifted register) performs a bitwise exclusive OR operation on a register value and a register-shifted register value. It updates the condition flags based on the result, and discards the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 0 1 1 Rn(4) 0 0 0 0 Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/tst_A88240.d b/src/arch/arm/v7/opdefs/tst_A88240.d index 9d4a8f9..0ff5121 100644 --- a/src/arch/arm/v7/opdefs/tst_A88240.d +++ b/src/arch/arm/v7/opdefs/tst_A88240.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,39 +23,41 @@ @title TST (immediate) -@encoding(T1) { +@desc Test (immediate) performs a bitwise AND operation on a register value and an immediate value. It updates the condition flags based on the result, and discards the result. - @word 1 1 1 1 0 i(1) 0 0 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) +@encoding (T1) { - @syntax <Rn> <const> + @word 1 1 1 1 0 i(1) 0 0 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm8(8) - @conv { + @syntax <reg_N> <imm32> - Rn = Register(Rn) - const = ThumbExpandImm_C(i:imm3:imm8, 0) + @conv { - } + reg_N = Register(Rn) + imm32 = ThumbExpandImm_C(i:imm3:imm8, 0) - @rules { + } - //if (n IN {13,15}) ; unpredictable +} - } +@encoding (A1) { -} + @word cond(4) 0 0 1 1 0 0 0 1 Rn(4) 0 0 0 0 imm12(12) -@encoding(A1) { + @syntax <reg_N> <imm32> - @word cond(4) 0 0 1 1 0 0 0 1 Rn(4) 0 0 0 0 imm12(12) + @conv { - @syntax {c} <Rn> <const> + reg_N = Register(Rn) + imm32 = ARMExpandImm_C(imm12, 0) - @conv { + } - c = Condition(cond) - Rn = Register(Rn) - const = ARMExpandImm_C(imm12, 0) + @rules { - } + chk_call StoreCondition(cond) + + } } + diff --git a/src/arch/arm/v7/opdefs/tst_A88241.d b/src/arch/arm/v7/opdefs/tst_A88241.d index 070fcb3..8777d06 100644 --- a/src/arch/arm/v7/opdefs/tst_A88241.d +++ b/src/arch/arm/v7/opdefs/tst_A88241.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,62 +23,58 @@ @title TST (register) -@encoding(t1) { +@desc Test (register) performs a bitwise AND operation on a register value and an optionally-shifted register value. It updates the condition flags based on the result, and discards the result. - @half 0 1 0 0 0 0 1 0 0 0 Rm(3) Rn(3) +@encoding (t1) { - @syntax <Rn> <Rm> + @half 0 1 0 0 0 0 1 0 0 0 Rm(3) Rn(3) - @conv { + @syntax <reg_N> <reg_M> - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_N = Register(Rn) + reg_M = Register(Rm) -} - -@encoding(T2) { - - @word 1 1 1 0 1 0 1 0 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) + } - @syntax <Rn> <Rm> <?shift> +} - @conv { +@encoding (T2) { - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm3:imm2) + @word 1 1 1 0 1 0 1 0 0 0 0 1 Rn(4) 0 imm3(3) 1 1 1 1 imm2(2) type(2) Rm(4) - } + @syntax ".W" <reg_N> <reg_M> <?shift> - @rules { + @conv { - //if n IN {13,15} || m IN {13,15} then UNPREDICTABLE + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm3:imm2) - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 1 0 0 0 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) + @word cond(4) 0 0 0 1 0 0 0 1 Rn(4) 0 0 0 0 imm5(5) type(2) 0 Rm(4) - @syntax {c} <Rn> <Rm> <?shift> + @syntax <reg_N> <reg_M> <?shift> - @conv { + @conv { - c = Condition(cond) - Rn = Register(Rn) - Rm = Register(Rm) - shift = DecodeImmShift(type, imm5) + reg_N = Register(Rn) + reg_M = Register(Rm) + shift = DecodeImmShift(type, imm5) - } + } - @rules { + @rules { - //if ((Rd == '1111') && (S == '1')) ; see SUBS PC, LR and related instructions + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/tst_A88242.d b/src/arch/arm/v7/opdefs/tst_A88242.d new file mode 100644 index 0000000..d3fdd9c --- /dev/null +++ b/src/arch/arm/v7/opdefs/tst_A88242.d @@ -0,0 +1,49 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title TST (register-shifted register) + +@desc Test (register-shifted register) performs a bitwise AND operation on a register value and a register-shifted register value. It updates the condition flags based on the result, and discards the result. + +@encoding (A1) { + + @word cond(4) 0 0 0 1 0 0 0 1 Rn(4) 0 0 0 0 Rs(4) 0 type(2) 1 Rm(4) + + @syntax <reg_N> <reg_M> <reg_shift> + + @conv { + + reg_shift = RegisterShift(type, Rs) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uadd16_A88243.d b/src/arch/arm/v7/opdefs/uadd16_A88243.d new file mode 100644 index 0000000..fcaadee --- /dev/null +++ b/src/arch/arm/v7/opdefs/uadd16_A88243.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UADD16 + +@desc Unsigned Add 16 performs two 16-bit unsigned integer additions, and writes the results to the destination register. It sets the APSR.GE bits according to the results of the additions. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 0 1 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 0 1 Rn(4) Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uadd8_A88244.d b/src/arch/arm/v7/opdefs/uadd8_A88244.d new file mode 100644 index 0000000..451ca79 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uadd8_A88244.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UADD8 + +@desc Unsigned Add 8 performs four unsigned 8-bit integer additions, and writes the results to the destination register. It sets the APSR.GE bits according to the results of the additions. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 0 1 Rn(4) Rd(4) 1 1 1 1 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uasx_A88245.d b/src/arch/arm/v7/opdefs/uasx_A88245.d new file mode 100644 index 0000000..f968527 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uasx_A88245.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UASX + +@desc Unsigned Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, and writes the results to the destination register. It sets the APSR.GE bits according to the results. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 0 1 Rn(4) Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/ubfx_A88246.d b/src/arch/arm/v7/opdefs/ubfx_A88246.d new file mode 100644 index 0000000..1f9488e --- /dev/null +++ b/src/arch/arm/v7/opdefs/ubfx_A88246.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UBFX + +@desc Unsigned Bit Field Extract extracts any number of adjacent bits at any position from a register, zero-extends them to 32 bits, and writes the result to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 1 0 0 Rn(4) 0 imm3(3) Rd(4) imm2(2) 0 widthm1(5) + + @syntax <reg_D> <reg_N> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + lsbit = UInt(imm3:imm2) + width = IncWidth(widthm1) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 1 1 1 widthm1(5) Rd(4) lsb(5) 1 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <lsbit> <width> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + lsbit = UInt(lsb) + width = IncWidth(widthm1) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/udf_A88247.d b/src/arch/arm/v7/opdefs/udf_A88247.d new file mode 100644 index 0000000..38f818c --- /dev/null +++ b/src/arch/arm/v7/opdefs/udf_A88247.d @@ -0,0 +1,69 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UDF + +@desc Permanently Undefined generates an Undefined Instruction exception. The encodings for UDF used in this section are defined as permanently UNDEFINED in the versions of the architecture specified in this section. Issue C.a of this manual first defines an assembler mnemonic for these encodings. However: • with the Thumb instruction set, ARM deprecates using the UDF instruction in an IT block • in the ARM instruction set, UDF is not conditional. + +@encoding (t1) { + + @half 1 1 0 1 1 1 1 0 imm8(8) + + @syntax <imm32> + + @conv { + + imm32 = ZeroExtend(imm8, 32) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 0 1 1 1 1 1 1 1 imm4(4) 1 0 1 0 imm12(12) + + @syntax ".W" <imm32> + + @conv { + + imm32 = ZeroExtend(imm4:imm12, 32) + + } + +} + +@encoding (A1) { + + @word 1 1 1 0 0 1 1 1 1 1 1 1 imm12(12) 1 1 1 1 imm4(4) + + @syntax <imm32> + + @conv { + + imm32 = ZeroExtend(imm12:imm4, 32) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/udiv_A88248.d b/src/arch/arm/v7/opdefs/udiv_A88248.d new file mode 100644 index 0000000..eea7947 --- /dev/null +++ b/src/arch/arm/v7/opdefs/udiv_A88248.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UDIV + +@desc Unsigned Divide divides a 32-bit unsigned integer register value by a 32-bit unsigned integer register value, and writes the result to the destination register. The condition flags are not affected. See ARMv7 implementation requirements and options for the divide instructions on page A4-172 for more information about this instruction. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 1 0 1 1 Rn(4) 1 1 1 1 Rd(4) 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 0 0 1 1 Rd(4) 1 1 1 1 Rm(4) 0 0 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uhadd16_A88249.d b/src/arch/arm/v7/opdefs/uhadd16_A88249.d new file mode 100644 index 0000000..54da5b0 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uhadd16_A88249.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UHADD16 + +@desc Unsigned Halving Add 16 performs two unsigned 16-bit integer additions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 1 Rn(4) Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uhadd8_A88250.d b/src/arch/arm/v7/opdefs/uhadd8_A88250.d new file mode 100644 index 0000000..759a0a7 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uhadd8_A88250.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UHADD8 + +@desc Unsigned Halving Add 8 performs four unsigned 8-bit integer additions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 1 Rn(4) Rd(4) 1 1 1 1 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uhasx_A88251.d b/src/arch/arm/v7/opdefs/uhasx_A88251.d new file mode 100644 index 0000000..3751394 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uhasx_A88251.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UHASX + +@desc Unsigned Halving Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 1 Rn(4) Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uhsax_A88252.d b/src/arch/arm/v7/opdefs/uhsax_A88252.d new file mode 100644 index 0000000..f06b2ba --- /dev/null +++ b/src/arch/arm/v7/opdefs/uhsax_A88252.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UHSAX + +@desc Unsigned Halving Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 1 0 Rn(4) 1 1 1 1 Rd(4) 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 1 Rn(4) Rd(4) 1 1 1 1 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uhsub16_A88253.d b/src/arch/arm/v7/opdefs/uhsub16_A88253.d new file mode 100644 index 0000000..93f92f7 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uhsub16_A88253.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UHSUB16 + +@desc Unsigned Halving Subtract 16 performs two unsigned 16-bit integer subtractions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 1 Rn(4) 1 1 1 1 Rd(4) 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 1 Rn(4) Rd(4) 1 1 1 1 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uhsub8_A88254.d b/src/arch/arm/v7/opdefs/uhsub8_A88254.d new file mode 100644 index 0000000..198a095 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uhsub8_A88254.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UHSUB8 + +@desc Unsigned Halving Subtract 8 performs four unsigned 8-bit integer subtractions, halves the results, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 0 Rn(4) 1 1 1 1 Rd(4) 0 1 1 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 1 Rn(4) Rd(4) 1 1 1 1 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/umaal_A88255.d b/src/arch/arm/v7/opdefs/umaal_A88255.d index 404f56f..34cb707 100644 --- a/src/arch/arm/v7/opdefs/umaal_A88255.d +++ b/src/arch/arm/v7/opdefs/umaal_A88255.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,51 +23,45 @@ @title UMAAL -@encoding(T1) { +@desc Unsigned Multiply Accumulate Accumulate Long multiplies two unsigned 32-bit values to produce a 64-bit value, adds two unsigned 32-bit values, and writes the 64-bit result to two registers. - @word 1 1 1 1 1 0 1 1 1 1 1 0 Rn(4) RdLo(4) RdHi(4) 0 1 1 0 Rm(4) +@encoding (T1) { - @syntax <RdLo> <RdHi> <Rn> <Rm> + @word 1 1 1 1 1 0 1 1 1 1 1 0 Rn(4) RdLo(4) RdHi(4) 0 1 1 0 Rm(4) - @conv { + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) - @rules { - - //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 0 1 0 0 RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 0 1 0 0 RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {c} <RdLo> <RdHi> <Rn> <Rm> + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - @conv { + @conv { - c = Condition(cond) - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) - } + } - @rules { + @rules { - //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/umlal_A88256.d b/src/arch/arm/v7/opdefs/umlal_A88256.d index fc17078..00d1903 100644 --- a/src/arch/arm/v7/opdefs/umlal_A88256.d +++ b/src/arch/arm/v7/opdefs/umlal_A88256.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,52 +23,47 @@ @title UMLAL -@encoding(T1) { +@desc Unsigned Multiply Accumulate Long multiplies two unsigned 32-bit values to produce a 64-bit value, and accumulates this with a 64-bit value. In ARM instructions, the condition flags can optionally be updated based on the result. Use of this option adversely affects performance on many processor implementations. - @word 1 1 1 1 1 0 1 1 1 1 1 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) +@encoding (T1) { - @syntax <RdLo> <RdHi> <Rn> <Rm> + @word 1 1 1 1 1 0 1 1 1 1 1 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) - @conv { + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) - @rules { - - //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 1 0 1 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 1 0 1 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') - } + } - @rules { + @rules { - //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/umull_A88257.d b/src/arch/arm/v7/opdefs/umull_A88257.d index ffed80b..d2cc321 100644 --- a/src/arch/arm/v7/opdefs/umull_A88257.d +++ b/src/arch/arm/v7/opdefs/umull_A88257.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,52 +23,47 @@ @title UMULL -@encoding(T1) { +@desc Unsigned Multiply Long multiplies two 32-bit unsigned values to produce a 64-bit result. In ARM instructions, the condition flags can optionally be updated based on the result. Use of this option adversely affects performance on many processor implementations. - @word 1 1 1 1 1 0 1 1 1 0 1 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) +@encoding (T1) { - @syntax <RdLo> <RdHi> <Rn> <Rm> + @word 1 1 1 1 1 0 1 1 1 0 1 0 Rn(4) RdLo(4) RdHi(4) 0 0 0 0 Rm(4) - @conv { + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + @conv { - } + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) - @rules { - - //if dLo IN {13,15} || dHi IN {13,15} || n IN {13,15} || m IN {13,15} then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; - - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 0 0 0 1 0 0 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) + @word cond(4) 0 0 0 0 1 0 0 S(1) RdHi(4) RdLo(4) Rm(4) 1 0 0 1 Rn(4) - @syntax {S} {c} <RdLo> <RdHi> <Rn> <Rm> + @syntax <reg_DLO> <reg_DHI> <reg_N> <reg_M> - @conv { + @conv { - S = SetFlags(S) - c = Condition(cond) - RdLo = Register(RdLo) - RdHi = Register(RdHi) - Rn = Register(Rn) - Rm = Register(Rm) + reg_DLO = Register(RdLo) + reg_DHI = Register(RdHi) + reg_N = Register(Rn) + reg_M = Register(Rm) + setflags = (S == '1') - } + } - @rules { + @rules { - //if dLo == 15 || dHi == 15 || n == 15 || m == 15 then UNPREDICTABLE; - //if dHi == dLo then UNPREDICTABLE; + if (setflags); chk_call ExtendKeyword("s") + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/uqadd16_A88258.d b/src/arch/arm/v7/opdefs/uqadd16_A88258.d new file mode 100644 index 0000000..14528c8 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uqadd16_A88258.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UQADD16 + +@desc Unsigned Saturating Add 16 performs two unsigned 16-bit integer additions, saturates the results to the 16-bit unsigned integer range 0 ≤ x ≤ 216 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 1 Rn(4) 1 1 1 1 Rd(4) 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 0 Rn(4) Rd(4) 1 1 1 1 0 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uqadd8_A88259.d b/src/arch/arm/v7/opdefs/uqadd8_A88259.d new file mode 100644 index 0000000..94b8e39 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uqadd8_A88259.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UQADD8 + +@desc Unsigned Saturating Add 8 performs four unsigned 8-bit integer additions, saturates the results to the 8-bit unsigned integer range 0 ≤ x ≤ 28 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 0 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 0 Rn(4) Rd(4) 1 1 1 1 1 0 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uqasx_A88260.d b/src/arch/arm/v7/opdefs/uqasx_A88260.d new file mode 100644 index 0000000..174b08c --- /dev/null +++ b/src/arch/arm/v7/opdefs/uqasx_A88260.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UQASX + +@desc Unsigned Saturating Add and Subtract with Exchange exchanges the two halfwords of the second operand, performs one unsigned 16-bit integer addition and one unsigned 16-bit subtraction, saturates the results to the 16-bit unsigned integer range 0 ≤ x ≤ 216 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 0 1 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 0 Rn(4) Rd(4) 1 1 1 1 0 0 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uqsax_A88261.d b/src/arch/arm/v7/opdefs/uqsax_A88261.d new file mode 100644 index 0000000..6092e51 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uqsax_A88261.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UQSAX + +@desc Unsigned Saturating Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, saturates the results to the 16-bit unsigned integer range 0 ≤ x ≤ 216 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 1 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 0 Rn(4) Rd(4) 1 1 1 1 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uqsub16_A88262.d b/src/arch/arm/v7/opdefs/uqsub16_A88262.d new file mode 100644 index 0000000..1f458ff --- /dev/null +++ b/src/arch/arm/v7/opdefs/uqsub16_A88262.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UQSUB16 + +@desc Unsigned Saturating Subtract 16 performs two unsigned 16-bit integer subtractions, saturates the results to the 16-bit unsigned integer range 0 ≤ x ≤ 216 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 1 Rn(4) 1 1 1 1 Rd(4) 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 0 Rn(4) Rd(4) 1 1 1 1 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uqsub8_A88263.d b/src/arch/arm/v7/opdefs/uqsub8_A88263.d new file mode 100644 index 0000000..37d96e7 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uqsub8_A88263.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UQSUB8 + +@desc Unsigned Saturating Subtract 8 performs four unsigned 8-bit integer subtractions, saturates the results to the 8-bit unsigned integer range 0 ≤ x ≤ 28 – 1, and writes the results to the destination register. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 1 0 Rn(4) Rd(4) 1 1 1 1 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usad8_A88264.d b/src/arch/arm/v7/opdefs/usad8_A88264.d new file mode 100644 index 0000000..09d7ece --- /dev/null +++ b/src/arch/arm/v7/opdefs/usad8_A88264.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USAD8 + +@desc Unsigned Sum of Absolute Differences performs four unsigned 8-bit subtractions, and adds the absolute values of the differences together. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 1 1 1 Rn(4) 1 1 1 1 Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 1 0 0 0 Rd(4) 1 1 1 1 Rm(4) 0 0 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usada8_A88265.d b/src/arch/arm/v7/opdefs/usada8_A88265.d new file mode 100644 index 0000000..dd1efdb --- /dev/null +++ b/src/arch/arm/v7/opdefs/usada8_A88265.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USADA8 + +@desc Unsigned Sum of Absolute Differences and Accumulate performs four unsigned 8-bit subtractions, and adds the absolute values of the differences to a 32-bit accumulate operand. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 1 0 1 1 1 Rn(4) Ra(4) Rd(4) 0 0 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 1 1 0 0 0 Rd(4) Ra(4) Rm(4) 0 0 0 1 Rn(4) + + @syntax <reg_D> <reg_N> <reg_M> <reg_A> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + reg_A = Register(Ra) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usat16_A88267.d b/src/arch/arm/v7/opdefs/usat16_A88267.d new file mode 100644 index 0000000..c091dc6 --- /dev/null +++ b/src/arch/arm/v7/opdefs/usat16_A88267.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USAT16 + +@desc Unsigned Saturate 16 saturates two signed 16-bit values to a selected unsigned range. The Q flag is set if the operation saturates. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 0 1 0 Rn(4) 0 0 0 0 Rd(4) 0 0 0 0 sat_imm(4) + + @syntax <reg_D> <saturate_to> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + saturate_to = UInt(sat_imm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 0 sat_imm(4) Rd(4) 1 1 1 1 0 0 1 1 Rn(4) + + @syntax <reg_D> <saturate_to> <reg_N> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + saturate_to = UInt(sat_imm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usat_A88266.d b/src/arch/arm/v7/opdefs/usat_A88266.d new file mode 100644 index 0000000..55de21a --- /dev/null +++ b/src/arch/arm/v7/opdefs/usat_A88266.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USAT + +@desc Unsigned Saturate saturates an optionally-shifted signed value to a selected unsigned range. The Q flag is set if the operation saturates. + +@encoding (T1) { + + @word 1 1 1 1 0 0 1 1 1 0 sh(1) 0 Rn(4) 0 imm3(3) Rd(4) imm2(2) 0 sat_imm(5) + + @syntax <reg_D> <saturate_to> <reg_N> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + saturate_to = UInt(sat_imm) + shift = DecodeImmShift(sh:'0', imm3:imm2) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 sat_imm(5) Rd(4) imm5(5) sh(1) 0 1 Rn(4) + + @syntax <reg_D> <saturate_to> <reg_N> <?shift> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + saturate_to = UInt(sat_imm) + shift = DecodeImmShift(sh:'0', imm5) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usax_A88268.d b/src/arch/arm/v7/opdefs/usax_A88268.d new file mode 100644 index 0000000..040eedc --- /dev/null +++ b/src/arch/arm/v7/opdefs/usax_A88268.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USAX + +@desc Unsigned Subtract and Add with Exchange exchanges the two halfwords of the second operand, performs one unsigned 16-bit integer subtraction and one unsigned 16-bit addition, and writes the results to the destination register. It sets the APSR.GE bits according to the results. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 1 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 0 1 Rn(4) Rd(4) 1 1 1 1 0 1 0 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usub16_A88269.d b/src/arch/arm/v7/opdefs/usub16_A88269.d new file mode 100644 index 0000000..31796d9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/usub16_A88269.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USUB16 + +@desc Unsigned Subtract 16 performs two 16-bit unsigned integer subtractions, and writes the results to the destination register. It sets the APSR.GE bits according to the results of the subtractions. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 1 Rn(4) 1 1 1 1 Rd(4) 0 1 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 0 1 Rn(4) Rd(4) 1 1 1 1 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/usub8_A88270.d b/src/arch/arm/v7/opdefs/usub8_A88270.d new file mode 100644 index 0000000..576894c --- /dev/null +++ b/src/arch/arm/v7/opdefs/usub8_A88270.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title USUB8 + +@desc Unsigned Subtract 8 performs four 8-bit unsigned integer subtractions, and writes the results to the destination register. It sets the APSR.GE bits according to the results of the subtractions. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 1 1 0 0 Rn(4) 1 1 1 1 Rd(4) 0 1 0 0 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 0 1 0 1 Rn(4) Rd(4) 1 1 1 1 1 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uxtab16_A88272.d b/src/arch/arm/v7/opdefs/uxtab16_A88272.d new file mode 100644 index 0000000..4fc61d2 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uxtab16_A88272.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UXTAB16 + +@desc Unsigned Extend and Add Byte 16 extracts two 8-bit values from a register, zero-extends them to 16 bits each, adds the results to two 16-bit values from another register, and writes the final results to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit values. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 0 0 1 1 Rn(4) 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 0 0 Rn(4) Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uxtab_A88271.d b/src/arch/arm/v7/opdefs/uxtab_A88271.d new file mode 100644 index 0000000..fe27d4b --- /dev/null +++ b/src/arch/arm/v7/opdefs/uxtab_A88271.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UXTAB + +@desc Unsigned Extend and Add Byte extracts an 8-bit value from a register, zero-extends it to 32 bits, adds the result to the value in another register, and writes the final result to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 0 1 0 1 Rn(4) 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 0 Rn(4) Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uxtah_A88273.d b/src/arch/arm/v7/opdefs/uxtah_A88273.d new file mode 100644 index 0000000..3c587d9 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uxtah_A88273.d @@ -0,0 +1,67 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UXTAH + +@desc Unsigned Extend and Add Halfword extracts a 16-bit value from a register, zero-extends it to 32 bits, adds the result to a value from another register, and writes the final result to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 0 0 0 1 Rn(4) 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 1 Rn(4) Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_N> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_N = Register(Rn) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uxtb16_A88275.d b/src/arch/arm/v7/opdefs/uxtb16_A88275.d new file mode 100644 index 0000000..a30d133 --- /dev/null +++ b/src/arch/arm/v7/opdefs/uxtb16_A88275.d @@ -0,0 +1,65 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UXTB16 + +@desc Unsigned Extend Byte 16 extracts two 8-bit values from a register, zero-extends them to 16 bits each, and writes the results to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit values. + +@encoding (T1) { + + @word 1 1 1 1 1 0 1 0 0 0 1 1 1 1 1 1 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) + + @syntax <reg_D> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 0 0 1 1 1 1 Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/uxtb_A88274.d b/src/arch/arm/v7/opdefs/uxtb_A88274.d index 8917144..f49ba83 100644 --- a/src/arch/arm/v7/opdefs/uxtb_A88274.d +++ b/src/arch/arm/v7/opdefs/uxtb_A88274.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,62 +23,58 @@ @title UXTB -@encoding(t1) { +@desc Unsigned Extend Byte extracts an 8-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 8-bit value. - @half 1 0 1 1 0 0 1 0 1 1 Rm(3) Rd(3) +@encoding (t1) { - @syntax <Rd> <Rm> + @half 1 0 1 1 0 0 1 0 1 1 Rm(3) Rd(3) - @conv { + @syntax <reg_D> <reg_M> - Rd = Register(Rd) - Rm = Register(Rm) + @conv { - } + reg_D = Register(Rd) + reg_M = Register(Rm) -} - -@encoding(T2) { - - @word 1 1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) + } - @syntax "uxtb.W" <Rd> <Rm> <?rotation> +} - @conv { +@encoding (T2) { - Rd = Register(Rd) - Rm = Register(Rm) - rotation = BuildRotation(rotate:'000') + @word 1 1 1 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) - } + @syntax ".W" <reg_D> <reg_M> <?rotation> - @rules { + @conv { - //if d IN {13,15} || m IN {13,15} then UNPREDICTABLE; + reg_D = Register(Rd) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') - } + } } -@encoding(A1) { +@encoding (A1) { - @word cond(4) 0 1 1 0 1 1 1 0 1 1 1 1 Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) + @word cond(4) 0 1 1 0 1 1 1 0 1 1 1 1 Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) - @syntax {c} <Rd> <Rm> <?rotation> + @syntax <reg_D> <reg_M> <?rotation> - @conv { + @conv { - c = Condition(cond) - Rd = Register(Rd) - Rm = Register(Rm) - rotation = BuildRotation(rotate:'000') + reg_D = Register(Rd) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') - } + } - @rules { + @rules { - //if d == 15 || m == 15 then UNPREDICTABLE; + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/opdefs/uxth_A88276.d b/src/arch/arm/v7/opdefs/uxth_A88276.d new file mode 100644 index 0000000..5ae4f4f --- /dev/null +++ b/src/arch/arm/v7/opdefs/uxth_A88276.d @@ -0,0 +1,80 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title UXTH + +@desc Unsigned Extend Halfword extracts a 16-bit value from a register, zero-extends it to 32 bits, and writes the result to the destination register. The instruction can specify a rotation by 0, 8, 16, or 24 bits before extracting the 16-bit value. + +@encoding (t1) { + + @half 1 0 1 1 0 0 1 0 1 0 Rm(3) Rd(3) + + @syntax <reg_D> <reg_M> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + + } + +} + +@encoding (T2) { + + @word 1 1 1 1 1 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 Rd(4) 1 0 rotate(2) Rm(4) + + @syntax ".W" <reg_D> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + +} + +@encoding (A1) { + + @word cond(4) 0 1 1 0 1 1 1 1 1 1 1 1 Rd(4) rotate(2) 0 0 0 1 1 1 Rm(4) + + @syntax <reg_D> <reg_M> <?rotation> + + @conv { + + reg_D = Register(Rd) + reg_M = Register(Rm) + rotation = Rotation(rotate:'000') + + } + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/wfi_A88425.d b/src/arch/arm/v7/opdefs/wfi_A88425.d new file mode 100644 index 0000000..f11d033 --- /dev/null +++ b/src/arch/arm/v7/opdefs/wfi_A88425.d @@ -0,0 +1,53 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * ##FILE## - traduction d'instructions ARMv7 + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +@title WFI + +@desc Wait For Interrupt is a hint instruction that permits the processor to enter a low-power state until one of a number of asynchronous events occurs. For more information, see Wait For Interrupt on page B1-1202. In an implementation that includes the Virtualization Extensions, if HCR.TWI is set to 1, execution of a WFI instruction in a Non-secure mode other than Hyp mode generates a Hyp Trap exception if, ignoring the value of the HCR.TWI bit, conditions permit the processor to suspend execution. For more information see Trapping use of the WFI and WFE instructions on page B1-1255. + +@encoding (t1) { + + @half 1 0 1 1 1 1 1 1 0 0 1 1 0 0 0 0 + +} + +@encoding (T2) { + + @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 + + @syntax ".W" + +} + +@encoding (A1) { + + @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 1 + + @rules { + + chk_call StoreCondition(cond) + + } + +} + diff --git a/src/arch/arm/v7/opdefs/yield_A88426.d b/src/arch/arm/v7/opdefs/yield_A88426.d index c0b4be0..252c018 100644 --- a/src/arch/arm/v7/opdefs/yield_A88426.d +++ b/src/arch/arm/v7/opdefs/yield_A88426.d @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * ##FILE## - traduction d'instructions ARMv7 * - * Copyright (C) 2014 Cyrille Bagard + * Copyright (C) 2015 Cyrille Bagard * * This file is part of Chrysalide. * @@ -23,28 +23,31 @@ @title YIELD -@encoding(t1) { +@desc YIELD is a hint instruction. Software with a multithreading capability can use a YIELD instruction to indicate to the hardware that it is performing a task, for example a spin-lock, that could be swapped out to improve overall system performance. Hardware can use this hint to suspend and resume multiple software threads if it supports the capability. For more information about the recommended use of this instruction see The Yield instruction on page A4-178. - @half 1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 0 +@encoding (t1) { + + @half 1 0 1 1 1 1 1 1 0 0 0 1 0 0 0 0 } -@encoding(T2) { +@encoding (T2) { - @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 + @word 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 -} + @syntax ".W" -@encoding(A1) { +} - @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 +@encoding (A1) { - @syntax {c} + @word cond(4) 0 0 1 1 0 0 1 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 1 - @conv { + @rules { - c = Condition(cond) + chk_call StoreCondition(cond) - } + } } + diff --git a/src/arch/arm/v7/operands/Makefile.am b/src/arch/arm/v7/operands/Makefile.am index a33e175..8cf73b8 100644 --- a/src/arch/arm/v7/operands/Makefile.am +++ b/src/arch/arm/v7/operands/Makefile.am @@ -2,6 +2,9 @@ noinst_LTLIBRARIES = libarcharmv7operands.la libarcharmv7operands_la_SOURCES = \ + coproc.h coproc.c \ + estate.h estate.c \ + limitation.h limitation.c \ maccess.h maccess.c \ offset.h offset.c \ reglist.h reglist.c \ diff --git a/src/arch/arm/v7/operands/coproc.c b/src/arch/arm/v7/operands/coproc.c new file mode 100644 index 0000000..c816b37 --- /dev/null +++ b/src/arch/arm/v7/operands/coproc.c @@ -0,0 +1,221 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * coproc.c - décallages de valeurs + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "coproc.h" + + +#include "../../../operand-int.h" + + + +/* Définition d'un opérande représentant un co-processeur (instance) */ +struct _GArmV7CoprocOperand +{ + GArchOperand parent; /* Instance parente */ + + uint8_t index; /* Indice du co-processeur */ + +}; + + +/* Définition d'un opérande représentant un co-processeur (classe) */ +struct _GArmV7CoprocOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des coprocs de domaine et d'accès. */ +static void g_armv7_coproc_operand_class_init(GArmV7CoprocOperandClass *); + +/* Initialise une instance de coproc de domaine et d'accès. */ +static void g_armv7_coproc_operand_init(GArmV7CoprocOperand *); + +/* Supprime toutes les références externes. */ +static void g_armv7_coproc_operand_dispose(GArmV7CoprocOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_coproc_operand_finalize(GArmV7CoprocOperand *); + +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_coproc_operand_print(const GArmV7CoprocOperand *, GBufferLine *, AsmSyntax); + + + +/* Indique le type défini par la GLib pour un co-processeur ARM. */ +G_DEFINE_TYPE(GArmV7CoprocOperand, g_armv7_coproc_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des co-processeurs ARM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_coproc_operand_class_init(GArmV7CoprocOperandClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + operand = G_ARCH_OPERAND_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_coproc_operand_dispose; + object->finalize = (GObjectFinalizeFunc)g_armv7_coproc_operand_finalize; + + operand->print = (operand_print_fc)g_armv7_coproc_operand_print; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance de co-processeur ARM. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_coproc_operand_init(GArmV7CoprocOperand *operand) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_coproc_operand_dispose(GArmV7CoprocOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_coproc_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_coproc_operand_finalize(GArmV7CoprocOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_coproc_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : raw = valeur brute du co-processeur à considérer. * +* * +* Description : Crée une représentation d'un co-processeur ARM. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_coproc_operand_new(uint8_t raw) +{ + GArmV7CoprocOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_COPROC_OPERAND, NULL); + + result->index = raw; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_coproc_operand_print(const GArmV7CoprocOperand *operand, GBufferLine *line, AsmSyntax syntax) +{ + char name[5]; /* Mot clef principal */ + size_t nlen; /* Taille de ce mot clef */ + + nlen = snprintf(name, sizeof(name), "p%hhu", operand->index); + + g_buffer_line_insert_text(line, BLC_ASSEMBLY, name, nlen, RTT_REGISTER); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Fournit l'indice d'un co-processeur ARM. * +* * +* Retour : Inditifiant représentant le co-processeur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +uint8_t g_armv7_coproc_operand_get_index(const GArmV7CoprocOperand *operand) +{ + return operand->index; + +} diff --git a/src/arch/arm/v7/operands/coproc.h b/src/arch/arm/v7/operands/coproc.h new file mode 100644 index 0000000..4920cef --- /dev/null +++ b/src/arch/arm/v7/operands/coproc.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * coproc.h - prototypes pour les décallages de valeurs + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_ARM_V7_OPERANDS_COPROC_H +#define _ARCH_ARM_V7_OPERANDS_COPROC_H + + +#include <glib-object.h> + + +#include "../../../operand.h" + + + +#define G_TYPE_ARMV7_COPROC_OPERAND g_armv7_coproc_operand_get_type() +#define G_ARMV7_COPROC_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_coproc_operand_get_type(), GArmV7CoprocOperand)) +#define G_IS_ARMV7_COPROC_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_coproc_operand_get_type())) +#define G_ARMV7_COPROC_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperandClass)) +#define G_IS_ARMV7_COPROC_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_COPROC_OPERAND)) +#define G_ARMV7_COPROC_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_COPROC_OPERAND, GArmV7CoprocOperandClass)) + + +/* Définition d'un opérande représentant un co-processeur (instance) */ +typedef struct _GArmV7CoprocOperand GArmV7CoprocOperand; + +/* Définition d'un opérande représentant un co-processeur (classe) */ +typedef struct _GArmV7CoprocOperandClass GArmV7CoprocOperandClass; + + +/* Indique le type défini par la GLib pour un co-processeur ARM. */ +GType g_armv7_coproc_operand_get_type(void); + +/* Crée une représentation d'un co-processeur ARM. */ +GArchOperand *g_armv7_coproc_operand_new(uint8_t); + +/* Fournit l'indice d'un co-processeur ARM. */ +uint8_t g_armv7_coproc_operand_get_index(const GArmV7CoprocOperand *); + + + +#endif /* _ARCH_ARM_V7_OPERANDS_COPROC_H */ diff --git a/src/arch/arm/v7/operands/estate.c b/src/arch/arm/v7/operands/estate.c new file mode 100644 index 0000000..214508a --- /dev/null +++ b/src/arch/arm/v7/operands/estate.c @@ -0,0 +1,219 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * endian.c - décallages de valeurs + * + * Copyright (C) 2010-2013 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "estate.h" + + +#include "../../../operand-int.h" + + + +/* Définition d'un opérande affichant le choix d'un boutisme (instance) */ +struct _GArmV7EndianOperand +{ + GArchOperand parent; /* Instance parente */ + + bool big; /* Grand boutisme à afficher ? */ + +}; + + +/* Définition d'un opérande affichant le choix d'un boutisme (classe) */ +struct _GArmV7EndianOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des affichages de boutisme. */ +static void g_armv7_endian_operand_class_init(GArmV7EndianOperandClass *); + +/* Initialise une instance d'affichage de boutisme. */ +static void g_armv7_endian_operand_init(GArmV7EndianOperand *); + +/* Supprime toutes les références externes. */ +static void g_armv7_endian_operand_dispose(GArmV7EndianOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *); + +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_endian_operand_print(const GArmV7EndianOperand *, GBufferLine *, AsmSyntax); + + + +/* Indique le type défini par la GLib pour une endian de domaine et d'accès. */ +G_DEFINE_TYPE(GArmV7EndianOperand, g_armv7_endian_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des affichages de boutisme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_endian_operand_class_init(GArmV7EndianOperandClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + operand = G_ARCH_OPERAND_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_endian_operand_dispose; + object->finalize = (GObjectFinalizeFunc)g_armv7_endian_operand_finalize; + + operand->print = (operand_print_fc)g_armv7_endian_operand_print; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance d'affichage de boutisme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_endian_operand_init(GArmV7EndianOperand *operand) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_endian_operand_dispose(GArmV7EndianOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_endian_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_endian_operand_finalize(GArmV7EndianOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_endian_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : big = indication sur le boutisme à représenter. * +* * +* Description : Crée une représentation de boutisme ARMv7. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_endian_operand_new(bool big) +{ + GArmV7EndianOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_ENDIAN_OPERAND, NULL); + + result->big = big; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_endian_operand_print(const GArmV7EndianOperand *operand, GBufferLine *line, AsmSyntax syntax) +{ + if (operand->big) + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "BE", 2, RTT_KEY_WORD); + else + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "LE", 2, RTT_KEY_WORD); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique le type de boutisme représenté. * +* * +* Retour : Type de boutisme. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *operand) +{ + return operand->big; + +} diff --git a/src/arch/arm/v7/operands/estate.h b/src/arch/arm/v7/operands/estate.h new file mode 100644 index 0000000..903c1ab --- /dev/null +++ b/src/arch/arm/v7/operands/estate.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * estate.h - prototypes pour le basculement de boutisme + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_ARM_V7_OPERANDS_ESTATE_H +#define _ARCH_ARM_V7_OPERANDS_ESTATE_H + + +#include <glib-object.h> + + +#include "../../../operand.h" + + + +#define G_TYPE_ARMV7_ENDIAN_OPERAND g_armv7_endian_operand_get_type() +#define G_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_endian_operand_get_type(), GArmV7EndianOperand)) +#define G_IS_ARMV7_ENDIAN_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_endian_operand_get_type())) +#define G_ARMV7_ENDIAN_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperandClass)) +#define G_IS_ARMV7_ENDIAN_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_ENDIAN_OPERAND)) +#define G_ARMV7_ENDIAN_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_ENDIAN_OPERAND, GArmV7EndianOperandClass)) + + +/* Définition d'un opérande affichant le choix d'un boutisme (instance) */ +typedef struct _GArmV7EndianOperand GArmV7EndianOperand; + +/* Définition d'un opérande affichant le choix d'un boutisme (classe) */ +typedef struct _GArmV7EndianOperandClass GArmV7EndianOperandClass; + + +/* Indique le type défini par la GLib pour une endian de domaine et d'accès. */ +GType g_armv7_endian_operand_get_type(void); + +/* Crée une représentation de boutisme ARMv7. */ +GArchOperand *g_armv7_endian_operand_new(bool); + +/* Indique le type de boutisme représenté. */ +bool g_armv7_endian_operand_is_big_endian(const GArmV7EndianOperand *); + + + +#endif /* _ARCH_ARM_V7_OPERANDS_ESTATE_H */ diff --git a/src/arch/arm/v7/operands/limitation.c b/src/arch/arm/v7/operands/limitation.c new file mode 100644 index 0000000..4d1d661 --- /dev/null +++ b/src/arch/arm/v7/operands/limitation.c @@ -0,0 +1,258 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * limitation.c - décallages de valeurs + * + * Copyright (C) 2010-2013 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "limitation.h" + + +#include "../../../operand-int.h" + + + +/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ +struct _GArmV7LimitationOperand +{ + GArchOperand parent; /* Instance parente */ + + BarrierLimitationType type; /* Type de limitation */ + +}; + + +/* Définition d'un opérande déterminant une limitation de domaine et d'accès (classe) */ +struct _GArmV7LimitationOperandClass +{ + GArchOperandClass parent; /* Classe parente */ + +}; + + +/* Initialise la classe des co-processeurs ARM. */ +static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass *); + +/* Initialise une instance de co-processeur ARM. */ +static void g_armv7_limitation_operand_init(GArmV7LimitationOperand *); + +/* Supprime toutes les références externes. */ +static void g_armv7_limitation_operand_dispose(GArmV7LimitationOperand *); + +/* Procède à la libération totale de la mémoire. */ +static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *); + +/* Traduit un opérande en version humainement lisible. */ +static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *, GBufferLine *, AsmSyntax); + + + +/* Indique le type défini par la GLib pour une limitation de domaine et d'accès. */ +G_DEFINE_TYPE(GArmV7LimitationOperand, g_armv7_limitation_operand, G_TYPE_ARCH_OPERAND); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des limitations de domaine et d'accès. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_limitation_operand_class_init(GArmV7LimitationOperandClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GArchOperandClass *operand; /* Version de classe parente */ + + object = G_OBJECT_CLASS(klass); + operand = G_ARCH_OPERAND_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_armv7_limitation_operand_dispose; + object->finalize = (GObjectFinalizeFunc)g_armv7_limitation_operand_finalize; + + operand->print = (operand_print_fc)g_armv7_limitation_operand_print; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance à initialiser. * +* * +* Description : Initialise une instance de limitation de domaine et d'accès. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_limitation_operand_init(GArmV7LimitationOperand *operand) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_limitation_operand_dispose(GArmV7LimitationOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_limitation_operand_parent_class)->dispose(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_limitation_operand_finalize(GArmV7LimitationOperand *operand) +{ + G_OBJECT_CLASS(g_armv7_limitation_operand_parent_class)->finalize(G_OBJECT(operand)); + +} + + +/****************************************************************************** +* * +* Paramètres : raw = valeur brute de la limitation à considérer. * +* * +* Description : Crée une représentation d'une limitation pour barrière. * +* * +* Retour : Opérande mis en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchOperand *g_armv7_limitation_operand_new(uint8_t raw) +{ + GArmV7LimitationOperand *result; /* Structure à retourner */ + + result = g_object_new(G_TYPE_ARMV7_LIMITATION_OPERAND, NULL); + + if (raw < 0b0010 || raw > 0b1111) + result->type = BLT_RESERVED; + + else + result->type = raw; + + return G_ARCH_OPERAND(result); + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à traiter. * +* line = ligne tampon où imprimer l'opérande donné. * +* syntax = type de représentation demandée. * +* * +* Description : Traduit un opérande en version humainement lisible. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_armv7_limitation_operand_print(const GArmV7LimitationOperand *operand, GBufferLine *line, AsmSyntax syntax) +{ + switch (operand->type) + { + case BLT_SY: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "SY", 2, RTT_KEY_WORD); + break; + + case BLT_ST: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ST", 2, RTT_KEY_WORD); + break; + + case BLT_ISH: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ISH", 3, RTT_KEY_WORD); + break; + + case BLT_ISHST: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "ISHST", 5, RTT_KEY_WORD); + break; + + case BLT_NSH: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "NSH", 3, RTT_KEY_WORD); + break; + + case BLT_NSHST: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "NSHST", 5, RTT_KEY_WORD); + break; + + case BLT_OSH: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "OSH", 3, RTT_KEY_WORD); + break; + + case BLT_OSHST: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "OSHST", 5, RTT_KEY_WORD); + break; + + default: + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "(reserved)", 10, RTT_KEY_WORD); + break; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * +* Description : Indique le type de limitation représentée. * +* * +* Retour : Type de limitation d'accès et de domaine. * +* * +* Remarques : - * +* * +******************************************************************************/ + +BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *operand) +{ + return operand->type; + +} diff --git a/src/arch/arm/v7/operands/limitation.h b/src/arch/arm/v7/operands/limitation.h new file mode 100644 index 0000000..1b2bcca --- /dev/null +++ b/src/arch/arm/v7/operands/limitation.h @@ -0,0 +1,77 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * limitation.h - prototypes pour les décallages de valeurs + * + * Copyright (C) 2016 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ARCH_ARM_V7_OPERANDS_LIMITATION_H +#define _ARCH_ARM_V7_OPERANDS_LIMITATION_H + + +#include <glib-object.h> + + +#include "../../../operand.h" + + + +#define G_TYPE_ARMV7_LIMITATION_OPERAND g_armv7_limitation_operand_get_type() +#define G_ARMV7_LIMITATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_armv7_limitation_operand_get_type(), GArmV7LimitationOperand)) +#define G_IS_ARMV7_LIMITATION_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_armv7_limitation_operand_get_type())) +#define G_ARMV7_LIMITATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperandClass)) +#define G_IS_ARMV7_LIMITATION_OPERAND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARMV7_LIMITATION_OPERAND)) +#define G_ARMV7_LIMITATION_OPERAND_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARMV7_LIMITATION_OPERAND, GArmV7LimitationOperandClass)) + + +/* Définition d'un opérande déterminant une limitation de domaine et d'accès (instance) */ +typedef struct _GArmV7LimitationOperand GArmV7LimitationOperand; + +/* Définition d'un opérande déterminant une limitation de domaine et d'accès (classe) */ +typedef struct _GArmV7LimitationOperandClass GArmV7LimitationOperandClass; + + +/* Types de limitation domaine & accès */ +typedef enum _BarrierLimitationType +{ + BLT_RESERVED = 0, + BLT_SY = 0b1111, + BLT_ST = 0b1110, + BLT_ISH = 0b1011, + BLT_ISHST = 0b1010, + BLT_NSH = 0b0111, + BLT_NSHST = 0b0110, + BLT_OSH = 0b0011, + BLT_OSHST = 0b0010 + +} BarrierLimitationType; + + +/* Indique le type défini par la GLib pour une limitation de domaine et d'accès. */ +GType g_armv7_limitation_operand_get_type(void); + +/* Crée une représentation d'une limitation pour barrière. */ +GArchOperand *g_armv7_limitation_operand_new(uint8_t); + +/* Indique le type de limitation représentée. */ +BarrierLimitationType g_armv7_limitation_operand_get_value(const GArmV7LimitationOperand *); + + + +#endif /* _ARCH_ARM_V7_OPERANDS_LIMITATION_H */ diff --git a/src/arch/arm/v7/operands/maccess.c b/src/arch/arm/v7/operands/maccess.c index 56ad0a3..e3e62fb 100644 --- a/src/arch/arm/v7/operands/maccess.c +++ b/src/arch/arm/v7/operands/maccess.c @@ -24,6 +24,9 @@ #include "maccess.h" +#include <assert.h> + + #include "../../../operand-int.h" @@ -36,6 +39,7 @@ struct _GArmV7MAccessOperand GArchOperand *base; /* Base de l'accès en mémoire */ GArchOperand *offset; /* Décallage pour l'adresse */ GArchOperand *shift; /* Décallage pour le décallage */ + bool not_post_indexed; /* Positio du décallage */ bool write_back; /* Mise à jour de la base */ }; @@ -164,10 +168,11 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand) /****************************************************************************** * * -* Paramètres : base = représente le registre de la base d'accès. * -* offset = détermine le décallage entre l'adresse et la base. * -* shift = opération de décallage pour jouer sur le décallage. * -* writeb = indique une mise à jour de la base après usage. * +* Paramètres : base = représente le registre de la base d'accès. * +* offset = détermine le décallage entre l'adresse et la base. * +* shift = opération de décallage pour jouer sur le décallage.* +* indexed = précise la forme donnée au décallage à appliquer. * +* wback = indique une mise à jour de la base après usage. * * * * Description : Crée un accès à la mémoire depuis une base et un décallage. * * * @@ -177,7 +182,7 @@ static void g_armv7_maccess_operand_finalize(GArmV7MAccessOperand *operand) * * ******************************************************************************/ -GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool writeb) +GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offset, GArchOperand *shift, bool indexed, bool wback) { GArmV7MAccessOperand *result; /* Structure à retourner */ @@ -186,7 +191,9 @@ GArchOperand *g_armv7_maccess_operand_new(GArchOperand *base, GArchOperand *offs result->base = base; result->offset = offset; result->shift = shift; - result->write_back = writeb; + + result->not_post_indexed = indexed; + result->write_back = wback; return G_ARCH_OPERAND(result); @@ -213,6 +220,9 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G g_arch_operand_print(operand->base, line, syntax); + if (!operand->not_post_indexed) + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK); + if (operand->offset != NULL) { g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); @@ -224,6 +234,8 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G if (operand->shift != NULL) { + assert(operand->not_post_indexed); + g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); @@ -231,7 +243,8 @@ static void g_armv7_maccess_operand_print(const GArmV7MAccessOperand *operand, G } - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK); + if (operand->not_post_indexed) + g_buffer_line_insert_text(line, BLC_ASSEMBLY, "]", 1, RTT_HOOK); if (operand->write_back) g_buffer_line_insert_text(line, BLC_ASSEMBLY, "!", 1, RTT_PUNCT); @@ -300,6 +313,25 @@ GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *oper * * * Paramètres : operand = opérande à consulter. * * * +* Description : Indique si le décallage est post-indexé. * +* * +* Retour : Statut des opérations menées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_armv7_maccess_operand_is_post_indexed(const GArmV7MAccessOperand *operand) +{ + return !operand->not_post_indexed; + +} + + +/****************************************************************************** +* * +* Paramètres : operand = opérande à consulter. * +* * * Description : Indique si la base est mise à jour après usage. * * * * Retour : Statut des opérations menées. * diff --git a/src/arch/arm/v7/operands/maccess.h b/src/arch/arm/v7/operands/maccess.h index 8684891..3bfd30e 100644 --- a/src/arch/arm/v7/operands/maccess.h +++ b/src/arch/arm/v7/operands/maccess.h @@ -53,7 +53,7 @@ typedef struct _GArmV7MAccessOperandClass GArmV7MAccessOperandClass; GType g_armv7_maccess_operand_get_type(void); /* Crée un accès à la mémoire depuis une base et un décallage. */ -GArchOperand *g_armv7_maccess_operand_new(GArchOperand *, GArchOperand *, GArchOperand *, bool); +GArchOperand *g_armv7_maccess_operand_new(GArchOperand *, GArchOperand *, GArchOperand *, bool, bool); /* Founit la base d'un accès à la mémoire. */ GArchOperand *g_armv7_maccess_operand_get_base(const GArmV7MAccessOperand *); @@ -64,6 +64,9 @@ GArchOperand *g_armv7_maccess_operand_get_offset(const GArmV7MAccessOperand *); /* Founit le décallage d'un décallage pour un accès mémoire. */ GArchOperand *g_armv7_maccess_operand_get_shift(const GArmV7MAccessOperand *); +/* Indique si le décallage est post-indexé. */ +bool g_armv7_maccess_operand_is_post_indexed(const GArmV7MAccessOperand *); + /* Indique si la base est mise à jour après usage. */ bool g_armv7_maccess_operand_has_to_write_back(const GArmV7MAccessOperand *); diff --git a/src/arch/arm/v7/register.c b/src/arch/arm/v7/register.c index f9bb731..31073ee 100644 --- a/src/arch/arm/v7/register.c +++ b/src/arch/arm/v7/register.c @@ -169,7 +169,7 @@ static void g_armv7_register_finalize(GArmV7Register *reg) GArmV7Register *g_armv7_register_new(uint8_t index) { - GArmV7Register *result; /* Structure à retourner */ + GArmV7Register *result; /* Structure à retourner */ result = g_object_new(G_TYPE_ARMV7_REGISTER, NULL); |