From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1635 invoked by alias); 20 Apr 2011 19:10:55 -0000 Received: (qmail 1584 invoked by uid 22791); 20 Apr 2011 19:10:40 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,RFC_ABUSE_POST,TW_EG,TW_NR,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-px0-f182.google.com (HELO mail-px0-f182.google.com) (209.85.212.182) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 20 Apr 2011 19:10:13 +0000 Received: by pxi20 with SMTP id 20so670780pxi.13 for ; Wed, 20 Apr 2011 12:10:12 -0700 (PDT) MIME-Version: 1.0 Received: by 10.143.24.40 with SMTP id b40mr4227847wfj.275.1303326612316; Wed, 20 Apr 2011 12:10:12 -0700 (PDT) Received: by 10.142.155.11 with HTTP; Wed, 20 Apr 2011 12:10:12 -0700 (PDT) Date: Wed, 20 Apr 2011 19:10:00 -0000 Message-ID: Subject: [PATCH] arm reversible From: oza Pawandeep To: gdb-patches@sourceware.org, gdb@sourceware.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-04/txt/msg00370.txt.bz2 Hi, I am working on phase-3 now. if anybody could please start reviewing phase-2 patch (as this is independent of phase-3 and could be checked in independently too) I may start implementing review comments as and when I get. In Parallel, test cases are also being worked upon. following is the phase-2 patch. PATCH STARTS. ------------------------------ diff -urN arm_orig/arm-linux-tdep.c arm_new/arm-linux-tdep.c --- arm_orig/arm-linux-tdep.c =C2=A0 =C2=A02011-03-03 09:21:13.000000000 +0= 530 +++ arm_new/arm-linux-tdep.c =C2=A0 =C2=A02011-04-15 13:11:15.000000000 +05= 30 @@ -998,6 +998,9 @@ =C2=A0 set_gdbarch_fetch_tls_load_module_address (gdbarch, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0svr4_fetch_objfile_link_map); + =C2=A0/* Enable process record */ + =C2=A0set_gdbarch_process_record(gdbarch, arm_process_record); + =C2=A0 tramp_frame_prepend_unwinder (gdbarch, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &arm_linux_sigretur= n_tramp_frame); =C2=A0 tramp_frame_prepend_unwinder (gdbarch, @@ -1025,6 +1028,8 @@ =C2=A0 tdep->syscall_next_pc =3D arm_linux_syscall_next_pc; + + =C2=A0tdep->arm_swi_record =3D NULL; =C2=A0} =C2=A0/* Provide a prototype to silence -Wmissing-prototypes. =C2=A0*/ diff -urN arm_orig/arm-tdep.c arm_new/arm-tdep.c --- arm_orig/arm-tdep.c =C2=A0 =C2=A02011-03-03 09:21:13.000000000 +0530 +++ arm_new/arm-tdep.c =C2=A0 =C2=A02011-04-15 13:11:15.000000000 +0530 @@ -54,8 +54,11 @@ =C2=A0#include "gdb_assert.h" =C2=A0#include "vec.h" +#include "record.h" + =C2=A0#include "features/arm-with-m.c" + =C2=A0static int arm_debug; =C2=A0/* Macros for setting and testing a bit in a minimal symbol that marks @@ -7929,3 +7932,1692 @@ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, /* FIXME: i18n= : "ARM debugging is %s. =C2=A0*/ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&setdebuglist, &show= debuglist); =C2=A0} + + + +/* arm-reversible process reacord data structures. =C2=A0*/ + +#define ARM_INSN_SIZE_BYTES 4 +#define THUMB_INSN_SIZE_BYTES 2 +#define THUMB2_INSN_SIZE_BYTES 4 +#define NO_OF_TYPE_OF_ARM_INSNS 8 +#define NO_OF_TYPE_OF_THUMB_INSNS 8 +#define ARM_RECORD_ARCH_LIST_ADD_REG(regnum) \ + =C2=A0 =C2=A0record_arch_list_add_reg (arm_record.regcache, regnum) +#define GET_REG_VAL(REGCACHE,NO,BUF) =C2=A0regcache_raw_read (REGCACHE, NO= , BUF); +#define INSN_S_L_BIT_NUM 20 + +struct arm_mem_r +{ + =C2=A0 =C2=A0uint32_t len; + =C2=A0 =C2=A0CORE_ADDR addr; +}; + +typedef struct insn_decode_record_t +{ + =C2=A0struct gdbarch *gdbarch; + =C2=A0struct regcache *regcache; + =C2=A0CORE_ADDR this_addr; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* address o= f the insn being decoded. =C2=A0*/ + =C2=A0uint32_t arm_insn; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* shou= ld accomodate thumb. =C2=A0*/ + =C2=A0uint32_t cond; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* condition code. =C2=A0*/ + =C2=A0uint32_t id; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* type of insn. =C2=A0*/ + =C2=A0uint32_t opcode; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/*= insn opcode. =C2=A0*/ + =C2=A0uint32_t decode; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/*= insn decode bits. =C2=A0*/ + =C2=A0uint32_t *arm_regs; =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* registers= to be saved for this record. =C2=A0*/ + =C2=A0struct arm_mem_r *arm_mems; =C2=A0 /* memory to be saved for this r= ecord. =C2=A0*/ +} insn_decode_record; + + +static int +SBO_SBZ (uint32_t insn, uint32_t bit_num, uint32_t len, uint32_t sbo) +{ + =C2=A0uint32_t ONES =3D bits (insn, bit_num - 1, (bit_num -1) + (len - 1)= ); + + =C2=A0if (!len) + =C2=A0 =C2=A0return 1; + + =C2=A0if(!sbo) + =C2=A0 =C2=A0ONES =3D ~ONES; + + =C2=A0while (ONES) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0if (!(ONES & sbo)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0ONES =3D ONES >> 1; + =C2=A0 =C2=A0} + =C2=A0return 1; +} + +static int +handle_extension_space (insn_decode_record *arm_record) +{ + =C2=A0insn_decode_record *arm_insn_r =3D arm_record; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D arm_insn_r->regcache; + + =C2=A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0; + =C2=A0uint32_t opcode1 =3D 0, opcode2 =3D 0; + + =C2=A0opcode1 =3D bits (arm_insn_r->arm_insn, 25, 27); + =C2=A0if ((3 =3D=3D opcode1) && (bit (arm_insn_r->arm_insn, 4))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* undefined instruction on ARM V5; need to handle if= later versions + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0define it. =C2=A0*/ + =C2=A0 =C2=A0} + + =C2=A0opcode2 =3D bits (arm_insn_r->arm_insn, 4, 7); + + =C2=A0if ((!opcode1) && (9 =3D=3D opcode2)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle arithmetic insn extension space. =C2=A0*/ + =C2=A0 =C2=A0} + + =C2=A0opcode1 =3D bits (arm_insn_r->arm_insn, 26, 27); + =C2=A0opcode2 =3D bits (arm_insn_r->arm_insn, 23, 24); + + =C2=A0if ((!opcode1) && (2 =3D=3D opcode2) && (!bit (arm_insn_r->arm_insn= , 20))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle control insn extension space. =C2=A0*/ + =C2=A0 =C2=A0} + + =C2=A0opcode1 =3D bits (arm_insn_r->arm_insn, 25, 27); + =C2=A0if ((!opcode1) && (bit (arm_insn_r->arm_insn, 7)) \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && (bit(arm_insn_= r->arm_insn, 4))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle load/store insn extension space. =C2=A0*/ + =C2=A0 =C2=A0} + + =C2=A0opcode1 =3D bits (arm_insn_r->arm_insn, 23, 27); + =C2=A0if ((24 =3D=3D opcode1) && (bit (arm_insn_r->arm_insn, 21))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle coprocessor insn extension space. =C2=A0*/ + =C2=A0 =C2=A0} + + =C2=A0/* to be done for ARMv5 and later; as of now we return -1. =C2=A0*/ + =C2=A0return -1; +} + +static int +arm_handle_data_proc_misc_load_str_insn (void *data) +{ + + =C2=A0insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D arm_insn_r->regcache; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf[2]; + + + =C2=A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0, reg_dest =3D 0; + =C2=A0uint32_t immed_high =3D 0, immed_low =3D 0,offset_8 =3D 0, tgt_mem_= addr =3D 0; + =C2=A0uint32_t opcode1 =3D 0; + + =C2=A0memset(&u_buf, 0, sizeof(u_buf)); + + =C2=A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); + =C2=A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); + =C2=A0opcode1 =3D bits (arm_insn_r->arm_insn, 20, 24); + + =C2=A0/* data processing insn /multiply insn. =C2=A0*/ + =C2=A0if ((9 =3D=3D arm_insn_r->decode) + =C2=A0 =C2=A0 && (((4 <=3D arm_insn_r->opcode) && (7 >=3D arm_insn_r->opc= ode)) + =C2=A0 =C2=A0 || =C2=A0((0 =3D=3D arm_insn_r->opcode) || (1 =3D=3D arm_in= sn_r->opcode)))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle multiply instructions. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((0 =3D=3D arm_insn_r->opcode) || (1 =3D=3D= arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* handle MLA and MUL. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32= _t*)xmalloc (sizeof(uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits= (arm_insn_r->arm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_= PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else if ((4 <=3D arm_insn_r->opcode) && (7 >= =3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* handle SMLAL, SMULL, UMLAL, UMULL. = =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs =3D (uint32_t*)xm= alloc (sizeof(uint32_t)*4); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs[0] =3D 3; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs[1] =3D bits (arm_= insn_r->arm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs[2] =3D bits (arm_= insn_r->arm_insn, 12, 15); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs[3] =3D ARM_PS_REG= NUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 } + =C2=A0 =C2=A0 =C2=A0} + =C2=A0else if ((bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0&& ((11 =3D=3D arm_insn_r->decode) || (13 =3D= =3D arm_insn_r->decode))) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* handle misc load insns, as 20th bit (L =3D = 1). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* LDR insn has a capability to do branching, = if + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0MOV LR, PC = is precedded by LDR insn having Rn as R15 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0in that cas= e, it emulates branch and link insn, and hence we + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0need to sav= e CSPR and PC as well. I am not sure this is right + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0place as op= code =3D 010 LDR insn make this happen, if R15 was + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0used. =C2= =A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_dest =3D bits (arm_insn_r->arm_insn, 12, 1= 5); + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (15 !=3D reg_dest) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32= _t*)xmalloc (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits= (arm_insn_r->arm_insn, 12, 15); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32= _t*)xmalloc (sizeof(uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D reg_= dest; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_= PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0} + =C2=A0else if (((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_insn_r->o= pcode)) + =C2=A0 =C2=A0 =C2=A0&& (SBO_SBZ (arm_insn_r->arm_insn, 5, 12, 0)) + =C2=A0 =C2=A0 =C2=A0&& (SBO_SBZ (arm_insn_r->arm_insn, 13, 4, 1)) + =C2=A0 =C2=A0 =C2=A0&& (2 =3D=3D bits (arm_insn_r->arm_insn, 20, 21))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle MSR insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*2); + =C2=A0 =C2=A0 =C2=A0if (9 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* CSPR is going to be changed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D ARM_PS_REGN= UM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SPSR is going to be changed. */ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Oza: FIX ME ? how to read SPSR value ? =C2= =A0*/ + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else if ((9 =3D=3D arm_insn_r->decode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && ((8 =3D=3D arm_insn_r->opcode) || (= 10 =3D=3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && (!bit (arm_insn_r->arm_insn, =C2=A0= INSN_S_L_BIT_NUM))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* Handling SWP, SWPB. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* these insns, changes register and memory as well. = =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* SWP or SWPB insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*2); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_mem_r *)xmalloc = (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0/* get memory address given by Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf[0].buf[0]); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0/* SWP insn ?, swaps word. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0if (8 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SWPB insn, swaps only byte. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D u_buf[0].s_word; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->arm_ins= n, 12, 15); + =C2=A0 =C2=A0} + =C2=A0else if ((3 =3D=3D arm_insn_r->decode) && (0x12 =3D=3D opcode1) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && (SBO_SBZ (arm_insn_r->arm_insn, 9, = 12, 1))) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle BLX, branch and link/exchange. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0if (9 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* branch is chosen by setting T bit of CSPR, = bitp[0] of Rm, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 and= R14 stores the return address. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (s= izeof(uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_LR_REGNUM; + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else if ((7 =3D=3D arm_insn_r->decode) && (0x12 =3D=3D opcode1)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle enhanced software breakpoint insn, BKPT */ + =C2=A0 =C2=A0 =C2=A0/* CPSR is changed to be executed in ARM state, =C2= =A0disabling normal + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 interrupts, entering abo= rt mode. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* accorindly to high vector configuration PC is set = accordingly */ + =C2=A0 =C2=A0 =C2=A0/* Oza: FIX ME ? =C2=A0what if user hit breakpoint an= d type reverse, in + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 that case, we need to go= back with previous CPSR and + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Program Counter. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*3); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_LR_REGNUM; + =C2=A0 =C2=A0 =C2=A0/* save SPSR also; how? =C2=A0*/ + =C2=A0 =C2=A0} + =C2=A0else if ((11 =3D=3D arm_insn_r->decode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&& (!bit (arm_insn_r->arm_insn, INSN_S_= L_BIT_NUM))) + =C2=A0{ + =C2=A0 =C2=A0/* handle enhanced store insns and DSP insns (e.g. LDRD) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 let us begin according to addressing m= odes for store insns + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 STRH insn, addresing modes are taken f= ollowing. =C2=A0*/ + =C2=A0 =C2=A0if ((14 =3D=3D arm_insn_r->opcode) || (10 =3D=3D arm_insn_r-= >opcode)) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 1) handle misc store, immediate offset. =C2= =A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("handling store insn, immed offfset ins= n\n"); + =C2=A0 =C2=A0 =C2=A0 =C2=A0immed_low =3D bits (arm_insn_r->arm_insn, 0, 3= ); + =C2=A0 =C2=A0 =C2=A0 =C2=A0immed_high =3D bits (arm_insn_r->arm_insn, 8, = 11); + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 1= 9); + =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf[0].bu= f[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (15 =3D=3D reg_src1) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* if R15 was used as Rn, hence = current PC+8. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_buf[0].s_word =3D u_buf[0].s_w= ord + 8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0offset_8 =3D (immed_high << 4) | immed_low; + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* calculate target store address. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (14 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[0].s_word= + offset_8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[0].s_word= - offset_8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_mem_r *)x= malloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].len =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D tgt_mem_addr; + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0else if ((12 =3D=3D arm_insn_r->opcode) || (8 =3D=3D arm_ins= n_r->opcode)) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 2) store, register offset. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get Rm. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 0, 3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src2 =3D bits (arm_insn_r->arm_insn, 16, 1= 9); + =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf[0].bu= f[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src2, &u_buf[1].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (15 =3D=3D reg_src2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* if R15 was used as Rn, hence = current PC+8. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_buf[0].s_word =3D u_buf[0].s_w= ord + 8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* calculate target store address, Rn +/- Rm, = register offset. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (12 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[0].s_word= + u_buf[1].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[1].s_word= - u_buf[0].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_mem_r *)x= malloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].len =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D tgt_mem_addr; + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0else if ((11 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_in= sn_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (2 =3D=3D arm_insn_r->opcode) || (6 =3D=3D arm_ins= n_r->opcode)) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 3) store, immediate pre-indexed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 5) =C2=A0store, immediate post-indexed. =C2= =A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0immed_low =3D bits (arm_insn_r->arm_insn, 0, 3= ); + =C2=A0 =C2=A0 =C2=A0 =C2=A0immed_high =3D bits (arm_insn_r->arm_insn, 8, = 11); + =C2=A0 =C2=A0 =C2=A0 =C2=A0offset_8 =3D (immed_high << 4) | immed_low; + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 1= 9); + =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL(reg_cache, reg_src1, &u_buf[0].buf= [0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* calculate target store address, Rn +/- Rm, = register offset. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((15 =3D=3D arm_insn_r->opcode) || (6 =3D= =3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[0].s_word= + offset_8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[0].s_word= - offset_8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_mem_r *)x= malloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].len =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D tgt_mem_addr; + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* record Rn also as it changes. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (s= izeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->= arm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0else if ((9 =3D=3D arm_insn_r->opcode) || (13 =3D=3D arm_ins= n_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (0 =3D=3D arm_insn_r->opcode) || (4 =3D=3D arm_ins= n_r->opcode)) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 4) store, register pre-indexed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 6) store, register post -indexed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 0, 3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src2 =3D bits (arm_insn_r->arm_insn, 16, 1= 9); + =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf[0].bu= f[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src2, &u_buf[1].bu= f[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* calculate target store address, Rn +/- Rm, = register offset. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((13 =3D=3D arm_insn_r->opcode) || (4 =3D= =3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[0].s_word= + u_buf[1].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf[1].s_word= - u_buf[0].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_mem_r *)x= malloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].len =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D tgt_mem_addr; + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* record Rn also as it changes. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (s= izeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->= arm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0/* DSP insns (e.g. LDRD) =C2=A0TBD. =C2=A0*/ + =C2=A0} + =C2=A0else if ((1 =3D=3D arm_insn_r->decode) && (0x12 =3D=3D opcode1) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && SBO_SBZ (arm_insn_r->arm_insn, 9, 1= 2, 1)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle BX, branch and link/exchange. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* branch is chosen by setting T bit of CSPR, bitp[0]= of Rm. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*2); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0} + =C2=A0else if ((1 =3D=3D arm_insn_r->decode) && (0x16 =3D=3D opcode1) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && SBO_SBZ (arm_insn_r->arm_insn, 9, 4= , 1) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && SBO_SBZ (arm_insn_r->arm_insn, 17, = 4, 1)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* count leading zeros: CLZ. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0printf("handling CLZ - count leading zero insn\n"); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*2); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->arm_ins= n, 12, 15); + =C2=A0 =C2=A0} + =C2=A0else if ((!bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&& ((8 =3D=3D arm_insn_r->opcode) || (1= 0 =3D=3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&& (SBO_SBZ (arm_insn_r->arm_insn, 17, = 4, 1)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&& (SBO_SBZ (arm_insn_r->arm_insn, 1, 1= 2, 0)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle MRS insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*2); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->arm_ins= n, 12, 15); + =C2=A0 =C2=A0} + =C2=A0/* following is always true, in case none of the above conditions m= eet, it will fall here. =C2=A0*/ + =C2=A0else if (arm_insn_r->opcode <=3D 15) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* normal data processing insns. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* out of 11 shifter operands mode, all the insn modi= fies destination + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register, which is= specified by 13-16 decode. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*3); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->arm_ins= n, 12, 15); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0} + =C2=A0return 0; +} + +static int +arm_handle_data_proc_imm_insn (void *data) +{ + =C2=A0insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D =C2=A0arm_insn_r->regcache; + + =C2=A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0, reg_dest =3D 0; + =C2=A0uint32_t immed_high =3D 0, immed_low =3D 0, offset_8 =3D 0, tgt_mem= _addr =3D 0; + + =C2=A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); + =C2=A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); + + =C2=A0if (((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_insn_r->opcode= )) + =C2=A0 =C2=A0 =C2=A0 && (2 =3D=3D bits (arm_insn_r->arm_insn, 20, 21)) + =C2=A0 =C2=A0 =C2=A0 && (SBO_SBZ (arm_insn_r->arm_insn, 13, 4, 1)) + =C2=A0 =C2=A0 =C2=A0 ) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle MSR insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*2); + =C2=A0 =C2=A0 =C2=A0if (9 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 /*CSPR is going to be changed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 arm_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0 } + =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 /* SPSR is going to be changed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 /* Oza: FIX ME ? how to read SPSR value? =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0/* following is always true, in case none of the above conditions m= eet, it will fall + =C2=A0 =C2=A0 =C2=A0 =C2=A0here. =C2=A0*/ + =C2=A0else if (arm_insn_r->opcode <=3D 15) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* normal data processing insns. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* out of 11 shifter operands mode, all the insn modi= fies destination + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register, which is= specified by 13-16 decode. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(u= int32_t)*3); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_insn_r->arm_ins= n, 12, 15); + =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0} + =C2=A0return 0; +} + +static int +arm_handle_ld_st_imm_offset_insn (void *data) +{ + =C2=A0insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D arm_insn_r->regcache; + + =C2=A0uint32_t reg_src1 =3D 0 , reg_src2=3D 0, reg_dest =3D 0; + =C2=A0uint32_t immed_high =3D 0, immed_low =3D 0, offset_12 =3D 0, tgt_me= m_addr =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0memset(&u_buf, 0, sizeof(u_buf)); + =C2=A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); + =C2=A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); + + =C2=A0if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0reg_dest =3D bits (arm_insn_r->arm_insn, 12, 15); + =C2=A0 =C2=A0 =C2=A0/* LDR insn has a capability to do branching, if + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0MOV LR, PC is precedded b= y LDR insn having Rn as R15 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0in that case, it emulates= branch and link insn, and hence we + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0need to save CSPR and PC = as well. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0if (15 !=3D reg_dest) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xma= lloc (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_i= nsn_r->arm_insn, 12, 15); + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xma= lloc (sizeof(uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D reg_dest; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_PS_REGN= UM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0if ((8 =3D=3D arm_insn_r->opcode) || (10 =3D=3D arm_i= nsn_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (12 =3D=3D arm_insn_r->opcode) || (14 =3D=3D arm_i= nsn_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_in= sn_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_i= nsn_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D arm_ins= n_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D arm_ins= n_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D arm_ins= n_r->opcode) + =C2=A0 =C2=A0 =C2=A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D arm_ins= n_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* store, immediate offset, immediate p= re-indexed, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0immediate post-indexed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn= , 16, 19); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0offset_12 =3D bits (arm_insn_r->arm_ins= n, 0, 11); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_bu= f.buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* U =3D=3D 1 */ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (bit (arm_insn_r->arm_insn, 23)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u_buf.s_= word + offset_12; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tgt_mem_addr =3D u_buf.s_word -= offset_12; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_me= m_r *)xmalloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D 1; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0switch(arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 8: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 12: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 9: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 13: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 1: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 5: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STR insn, STRT = insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_me= ms[1].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 10: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 14: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 11: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 15: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 3: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 7: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STRB insn, STRB= T insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_me= ms[1].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0default: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* rest of the ins= ns are unreachable for this addressing mode. */ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D tgt_me= m_addr; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((9 =3D=3D arm_insn_r->opcode) || (1= 1 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (13 =3D=3D arm_insn_r->opcode) || (1= 5 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (0 =3D=3D arm_insn_r->opcode) || (2 = =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (4 =3D=3D arm_insn_r->opcode) || (6 = =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (1 =3D=3D arm_insn_r->opcode) || (3 = =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (5 =3D=3D arm_insn_r->opcode) || (7 = =3D=3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* we are handling pre-in= dexed mode; post-indexed mode; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 where Rn is going to be changed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D = (uint32_t*)xmalloc (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] = =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] = =3D reg_src1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0return 0; +} + +static int +arm_handle_ld_st_reg_offset_insn (void *data) +{ + =C2=A0insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D =C2=A0arm_insn_r->regcache; + + =C2=A0uint32_t shift_imm =3D 0; + =C2=A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0, reg_dest =3D 0; + =C2=A0uint32_t immed_high =3D 0, immed_low =3D 0, offset_12 =3D 0, tgt_me= m_addr =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0int32_t signed_word; + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf[2]; + + =C2=A0memset(&u_buf, 0, sizeof(u_buf)); + =C2=A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); + =C2=A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); + + =C2=A0/* handle enhanced store insns and LDRD DSP insn, + =C2=A0 =C2=A0 =C2=A0 =C2=A0let us begin according to addressing modes for= store insns + =C2=A0 =C2=A0 =C2=A0 =C2=A0STRH insn. =C2=A0*/ + + =C2=A0/* LDR or STR? =C2=A0*/ + =C2=A0if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0reg_dest =3D bits (arm_insn_r->arm_insn, 12, 15); + =C2=A0 =C2=A0 =C2=A0/* LDR insn has a capability to do branching, if + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0MOV LR, PC is precedded b= y LDR insn having Rn as R15 + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0in that case, it emulates= branch and link insn, and hence we + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0need to save CSPR and PC = as well. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0if (15 !=3D reg_dest) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xma= lloc (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D bits (arm_i= nsn_r->arm_insn, 12, 15); + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xma= lloc (sizeof(uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D reg_dest; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[2] =3D ARM_PS_REGN= UM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0if ((8 =3D=3D arm_insn_r->opcode) || (10 =3D=3D arm_insn_r->= opcode) + =C2=A0 =C2=A0|| (12 =3D=3D arm_insn_r->opcode) || (14 =3D=3D arm_insn_r->= opcode) + =C2=A0 =C2=A0|| (9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_insn_r->o= pcode) + =C2=A0 =C2=A0|| (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_insn_r->= opcode) + =C2=A0 =C2=A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D arm_insn_r->op= code) + =C2=A0 =C2=A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D arm_insn_r->op= code) + =C2=A0 =C2=A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D arm_insn_r->op= code) + =C2=A0 =C2=A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D arm_insn_r->op= code)) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (! bits (arm_insn_r->arm_insn, 4, 11)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* store insn, register offset a= nd register pre-indexed, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0register post-indexed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get Rm. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->a= rm_insn, 0, 3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src2 =3D bits (arm_insn_r->a= rm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1= , &u_buf[0].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src2, &u_buf[1].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (15 =3D=3D reg_src2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* if R15 was used= as Rn, hence current PC+8. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* pre-indexed mod= e doesnt reach here ; illegal insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0u_buf[0].s_word = =3D u_buf[0].s_word + 8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* calculate target store addres= s, Rn +/- Rm, register offset. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* U =3D=3D 1. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (bit (arm_insn_r->arm_insn, 2= 3)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u= _buf[0].s_word + u_buf[1].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u= _buf[1].s_word - u_buf[0].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct= arm_mem_r *)xmalloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D = 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0switch(arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 8: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 12: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 9: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 13: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 1: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 5: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STR insn= , STRT insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r-= >arm_mems[1].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 10: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 14: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 11: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 15: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 3: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 7: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STRB ins= n, STRBT insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r-= >arm_mems[1].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0default: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* rest of = the insns are unreachable for this addr mode. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D= tgt_mem_addr; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((9 =3D=3D arm_insn_r->opcode= ) || (11 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (13 =3D=3D arm_insn_r->opcode= ) || (15 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (0 =3D=3D arm_insn_r->opcode)= || (2 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (4 =3D=3D arm_insn_r->opcode)= || (6 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (1 =3D=3D arm_insn_r->opcode)= || (3 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (5 =3D=3D arm_insn_r->opcode)= || (7 =3D=3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs =3D \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint32_t*)xmalloc= (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Rn is going to = be changed in pre-indexed mode and + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0post-indexed mode as well. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs[1] =3D reg_src2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* store insn, scaled register o= ffset; scaled pre-indexed. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0offset_12 =3D bits (arm_insn_r->= arm_insn, 5, 6); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get Rm. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->a= rm_insn, 0, 3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src2 =3D bits (arm_insn_r->a= rm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* get shift_imm. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0shift_imm =3D bits (arm_insn_r->= arm_insn, 7, 11); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1= , &u_buf[0].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src2= , &u_buf[1].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* offset_12 used as shift. =C2= =A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0switch(offset_12) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* offset_1= 2 used as index. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0offset_12 = =3D u_buf[0].s_word << shift_imm; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 1: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0offset_12 = =3D (!shift_imm)?0:u_buf[0].s_word >> shift_imm; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 2: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!shift_= imm) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0if (bit (u_buf[0].s_word, 31)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0offset_12 =3D 0xFFFFFFFF; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0offset_12 =3D 0; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* this is arithmetic shift. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0offset_12 =3D u_buf[0].signed_word >> shift_imm; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 3: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (!shift_= imm) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0GET_REG_VAL (reg_cache, ARM_PS_REGNUM, &u_buf[1].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0/* get C flag value and shift it by 31. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0offset_12 =3D (((bit (u_buf[1].s_word, 29)) << 31) \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| (u_buf[0].s_word) >> = 1); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0offset_12 =3D (u_buf[0].s_word >> shift_imm) \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0| (u_buf[0].s_word << (sizeof(uint32_t)-shift_imm)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0default: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* unreacha= ble. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src2= , &u_buf[1].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* U =3D=3D 1 */ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (bit (arm_insn_r->arm_insn, 2= 3)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u= _buf[1].s_word + offset_12; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tgt_mem_addr =3D u= _buf[1].s_word - offset_12; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct= arm_mem_r *) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0xmalloc (sizeof(struct arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D = 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[1].addr =3D= tgt_mem_addr; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0switch (arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 8: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 12: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 9: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 13: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 1: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 5: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STR insn= , STRT insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r-= >arm_mems[1].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 10: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 14: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 11: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 15: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 3: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0case 7: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STRB ins= n, STRBT insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r-= >arm_mems[1].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0default: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* rest of = the insns are unreachable for this addr mode. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((9 =3D=3D arm_insn_r->opcode= ) || (11 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (13 =3D=3D arm_insn_r->opcode= ) || (15 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (0 =3D=3D arm_insn_r->opcode)= || (2 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (4 =3D=3D arm_insn_r->opcode)= || (6 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (1 =3D=3D arm_insn_r->opcode)= || (3 =3D=3D arm_insn_r->opcode) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| (5 =3D=3D arm_insn_r->opcode)= || (7 =3D=3D arm_insn_r->opcode)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs =3D \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(uint32_t*)xmalloc= (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Rn is going to = be changed in register scaled pre-indexed + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0mode, and scaled post indexed mode. = =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs[1] =3D reg_src2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0return 0; +} + +static int +arm_hamdle_ld_st_multiple_insn (void *data) +{ + =C2=A0insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D =C2=A0arm_insn_r->regcache; + + =C2=A0uint32_t register_list[16]=3D{0}, register_count=3D0, register_bits= =3D0; + =C2=A0uint32_t shift_imm=3D0; + =C2=A0uint32_t reg_src1=3D0, reg_src2=3D0, addr_mode=3D0; + =C2=A0uint32_t start_address=3D0, index =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf[2]; + + =C2=A0memset (&u_buf, 0, sizeof(u_buf)); + + =C2=A0/* this mode is exclusively for load and store multiple. =C2=A0*/ + =C2=A0/* handle incremenrt after/before and decrment after.before mode; + =C2=A0 =C2=A0 =C2=A0 =C2=A0Rn is chaging depending on W bit, but as of no= w we store Rn too wihtout going for + =C2=A0 =C2=A0 =C2=A0 =C2=A0optmization. =C2=A0*/ + + + =C2=A0if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* LDR (1,2,3) where LDR (3) changes CPSR too. =C2=A0= */ + + =C2=A0 =C2=A0 =C2=A0register_bits =3D bits (arm_insn_r->arm_insn, 0, 15); + =C2=A0 =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); + =C2=A0 =C2=A0 =C2=A0while (register_bits) + =C2=A0 =C2=A0 =C2=A0 { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (register_bits & 0x00000001) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 register_list[register_count++] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 register_bits =3D register_bits >> 1; + =C2=A0 =C2=A0 =C2=A0 } + + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* extra space for Base Register and CPSR; wih= tout optmization. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(sizeof(uint32_t= ) * (register_count + 3)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D register_count + 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[register_count+1] =3D reg= _src1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_regs[register_count+2] =3D ARM= _PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0for (register_count =3D 0; register_count < 8;= register_count++) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if =C2=A0(register_list[register= _count]) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_re= gs[index] =3D register_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0index++; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0/* it handles both STM(1) and STM(2). =C2=A0*/ + =C2=A0 =C2=A0addr_mode =3D bits (arm_insn_r->arm_insn, 23, 24); + + =C2=A0 =C2=A0register_bits =3D bits (arm_insn_r->arm_insn, 0, 15); + =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); + =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf[0].buf[0]); + =C2=A0 =C2=A0while (register_bits) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (register_bits & 0x00000001) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 register_count++; + =C2=A0 =C2=A0 =C2=A0 =C2=A0register_bits =3D register_bits >> 1; + =C2=A0 =C2=A0 =C2=A0} + + =C2=A0 =C2=A0switch(addr_mode) + =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Decrement after. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 0: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D (u_buf[0].s_word) - (= register_count * 4) + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_me= m_r *)xmalloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*(register_count+1)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D registe= r_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0while (register_count) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].addr =3D start_address; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D start_a= ddress + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_count--; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Increment after. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 1: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D u_buf[0].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_me= m_r *)xmalloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*(register_count+1)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D registe= r_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0while (register_count) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].addr =3D start_address; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D start_a= ddress + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_count--; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Decrement before. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 2: + + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D (u_buf[0].s_word) - (= register_count * 4); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_me= m_r *)xmalloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*(register_count+1)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D registe= r_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0while (register_count) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].addr =3D start_address; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D start_a= ddress + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_count--; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Increment before. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0case 3: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D u_buf[0].s_word + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems =3D (struct arm_me= m_r *)xmalloc (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*(register_count+1)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[0].len =3D registe= r_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0while (register_count) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].addr =3D start_address; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_insn_r->arm_mems[regi= ster_count].len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D start_a= ddress + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_count--; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + + =C2=A0 =C2=A0 =C2=A0 =C2=A0default: + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* unreachable. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0break; + =C2=A0 =C2=A0 =C2=A0} + + =C2=A0 =C2=A0/* base register also changes; based on condition and W bit.= =C2=A0*/ + =C2=A0 =C2=A0/* we save it anyway without optimization. =C2=A0*/ + =C2=A0 =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(uint32_t= )*2); + =C2=A0 =C2=A0arm_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0arm_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0} + =C2=A0return 0; +} + +static int +arm_handle_brn_insn (void *data) +{ + =C2=A0insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0/* handle B, BL, BLX(1) insns. =C2=A0*/ + =C2=A0/* wihtout optmization we save link register, + =C2=A0 =C2=A0 =C2=A0 =C2=A0CSPR for the insn which changes T bit. =C2=A0*/ + =C2=A0arm_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(uint32_t)*3); + =C2=A0arm_insn_r->arm_regs[0] =3D 2; + =C2=A0arm_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0arm_insn_r->arm_regs[2] =3D ARM_LR_REGNUM; + + =C2=A0return 0; +} + +static int +arm_handle_coproc_insn (void *data) +{ + =C2=A0 return -1; +} + +static int +arm_handle_coproc_data_proc_insn (void *data) +{ + + =C2=A0 insn_decode_record *arm_insn_r =3D (insn_decode_record*) data; + =C2=A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); + =C2=A0 struct regcache *reg_cache =3D arm_insn_r->regcache; + + =C2=A0 uint32_t shift_imm =3D 0; + =C2=A0 uint32_t reg_src1 =3D 0, reg_src2 =3D 0, addr_mode =3D 0; + =C2=A0 uint32_t start_address =3D 0; + + =C2=A0 /* handle SWI insn; system call would be handled over here. =C2=A0= */ + + =C2=A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 24, 27); + =C2=A0 if (15 =3D=3D arm_insn_r->opcode) + =C2=A0 { + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* handle arm syscall insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (tdep->arm_swi_record !=3D NULL) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tdep->arm_swi_record(reg_cache); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 } + + =C2=A0 return -1; +} + + +static int +thumb_handle_shift_add_sub_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep ( =C2=A0thumb_insn_r->gd= barch); + =C2=A0struct regcache *reg_cache =3D =C2=A0thumb_insn_r->regcache; + + =C2=A0uint32_t reg_src1 =3D 0; + + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); + + =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(uint32_t)*3); + =C2=A0thumb_insn_r->arm_regs[0] =3D 2; + =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0thumb_insn_r->arm_regs[2] =3D reg_src1; + + =C2=A0return 0; +} + +static int +thumb_handle_add_sub_cmp_mov_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D thumb_insn_r->regcache; + + =C2=A0uint32_t reg_src1 =3D 0; + + + =C2=A0union + =C2=A0{ + =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0} u_buf; + + =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + + =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(uint32_t)*3); + =C2=A0thumb_insn_r->arm_regs[0] =3D 2; + =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0thumb_insn_r->arm_regs[2] =3D reg_src1; + + =C2=A0return 0; +} + +static int +thumb_handle_ld_st_reg_offset_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D =C2=A0thumb_insn_r->regcache; + + =C2=A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0; + =C2=A0uint32_t opcode1 =3D 0, opcode2 =3D 0, opcode3 =3D 0; + + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf[2]; + + =C2=A0if (bit (thumb_insn_r->arm_insn, 12)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle load/store register offset. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0opcode1 =3D bits (thumb_insn_r->arm_insn, 11, 12); + =C2=A0 =C2=A0 =C2=A0opcode2 =3D bits (thumb_insn_r->arm_insn, 9, 10); + =C2=A0 =C2=A0 =C2=A0if ((opcode2 >=3D 12) && (opcode2 <=3D 15)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* LDR(2), LDRB(2) , LDRH(2), LDRSB, LD= RSH. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_in= sn,0, 2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)x= malloc (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0else if ((opcode2 >=3D 8) && (opcode2 <=3D 10)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* STR(2), STRB(2), STRH(2) . =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_in= sn, 3, 5); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src2 =3D bits (thumb_insn_r->arm_in= sn, 6, 8); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_bu= f[0].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src2, &u_bu= f[1].buf[0]); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems =3D (struct arm_= mem_r *) =C2=A0\ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0xmalloc (sizeof(struct = arm_mem_r) * 2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].addr =3D u_bu= f[0].s_word+u_buf[1].s_word; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (8 =3D=3D opcode2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len = =3D 4; =C2=A0 =C2=A0/* STR (2). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else if (10 =3D=3D opcode2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len = =3D 1; =C2=A0 =C2=A0/* =C2=A0STRB (2). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0else if (9 =3D=3D opcode2) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len = =3D 2; =C2=A0 =C2=A0/* STRH (2). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0goto end; + =C2=A0 =C2=A0} + =C2=A0else if (bit (thumb_insn_r->arm_insn, 11)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* handle load from literal pool. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* LDR(3). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0 =C2=A0goto end; + =C2=A0 =C2=A0} + + =C2=A0thumb_insn_r->opcode =3D bits (thumb_insn_r->arm_insn, 13, 15); + =C2=A0opcode1 =3D bits (thumb_insn_r->arm_insn, 10, 12); + =C2=A0if (opcode1) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0opcode2 =3D bits (thumb_insn_r->arm_insn, 8, 9); + =C2=A0 =C2=A0 =C2=A0opcode3 =3D bits (thumb_insn_r->arm_insn, 0, 2); + =C2=A0 =C2=A0 =C2=A0if ((3 =3D=3D opcode2) && (!opcode3)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* branch with exchange. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)x= malloc (sizeof(uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_RE= GNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* format 8; special data processing in= sns. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_in= sn, 0, 2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)x= malloc (sizeof(uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_RE= GNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[2] =3D reg_src1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* format 5; data processing insns. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); + =C2=A0 =C2=A0 =C2=A0if (bit (thumb_insn_r->arm_insn, 7)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0reg_src1 =3D reg_src1 + 8; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[2] =3D reg_src1; + =C2=A0 =C2=A0} + + =C2=A0end: + =C2=A0return 0; +} + +static int +thumb_handle_ld_st_imm_offset_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D (struct regcache*) thumb_insn_r->reg= cache; + + =C2=A0uint32_t reg_val1 =3D 0; + =C2=A0uint32_t reg_src1 =3D 0; + =C2=A0uint32_t opcode =3D 0, immed_5 =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); + + =C2=A0if (opcode) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* LDR(1). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0} + =C2=A0else + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* STR(1). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 3, 5); + =C2=A0 =C2=A0 =C2=A0immed_5 =3D bits (thumb_insn_r->arm_insn, 6, 10); + =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf.buf[0]); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems =3D (struct arm_mem_r *)xmallo= c (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[1].len =3D 4; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[1].addr =3D u_buf.s_word + (im= med_5 * 4); + =C2=A0 =C2=A0} + + =C2=A0return 0; +} + +static int +thumb_hamdle_ld_st_stack_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D (struct regcache*) thumb_insn_r->reg= cache; + + =C2=A0uint32_t reg_val1 =3D 0; + =C2=A0uint32_t reg_src1 =3D 0; + =C2=A0uint32_t opcode =3D 0, immed_8 =3D 0, immed_5 =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); + + =C2=A0if (3 =3D=3D opcode) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* LDR(4). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0} + =C2=A0else if (1 =3D=3D opcode) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* LDRH(1). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0} + =C2=A0else if (2 =3D=3D opcode) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* STR(3). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0immed_8 =3D bits (thumb_insn_r->arm_insn, 0, 7); + =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, ARM_SP_REGNUM, &u_buf.buf[0]); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems =3D (struct arm_mem_r *)xmallo= c (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[1].len =3D 4; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[1].addr =3D u_buf.s_word + (im= med_8 * 4); + =C2=A0 =C2=A0} + =C2=A0else if (0 =3D=3D opcode) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* STRH(1). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0immed_5 =3D bits (thumb_insn_r->arm_insn, 6, 10); + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 3, 5); + =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf.buf[0]); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems =3D (struct arm_mem_r *)xmallo= c (sizeof(struct + =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_mem_r)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[1].len =3D 2; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[1].addr =3D u_buf.s_word + (im= med_5 * 2); + =C2=A0 =C2=A0} + =C2=A0return 0; +} + +static int +thumb_handle_misc_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D (struct regcache*) thumb_insn_r->reg= cache; + + =C2=A0uint32_t reg_val1 =3D 0; + =C2=A0uint32_t reg_src1 =3D 0; + =C2=A0uint32_t opcode =3D 0, opcode1 =3D 0, opcode2 =3D 0, immed_8 =3D 0,= immed_5 =3D 0; + =C2=A0uint32_t register_bits =3D 0, register_count =3D 0; + =C2=A0uint32_t register_list[8] =3D {0}, index =3D 0, start_address =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); + =C2=A0opcode1 =3D bits (thumb_insn_r->arm_insn, 8, 12); + =C2=A0opcode2 =3D bits (thumb_insn_r->arm_insn, 9, 12); + + =C2=A0if (14 =3D=3D opcode2) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* POP. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); + =C2=A0 =C2=A0 =C2=A0while (register_bits) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (register_bits & 0x00000001) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_list[register_count++] = =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_bits =3D register_bits >> 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(sizeof(uint32_t= ) * (register_count + 3)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D register_count += 2; + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[register_count + 1] =3D= ARM_PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[register_count + 2] =3D= ARM_SP_REGNUM; + =C2=A0 =C2=A0 =C2=A0for (register_count =3D 0; register_count < 8; regist= er_count++) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if =C2=A0(register_list[register_count]) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[in= dex] =3D register_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0index++; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else if (10 =3D=3D opcode2) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* PUSH. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); + =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, ARM_PC_REGNUM, &u_buf.buf[0]); + =C2=A0 =C2=A0 =C2=A0while (register_bits) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (register_bits & 0x00000001) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 register_count++; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_bits =3D register_bits >> 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0start_address =3D u_buf.s_word - =C2=A0\ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (4 * (bit = (thumb_insn_r->arm_insn, 8) + register_count)) ; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems =3D (struct arm_mem_r *)xmallo= c (sizeof(struct + =C2=A0 =C2=A0 =C2=A0arm_mem_r)*(register_count + 1)); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len =3D register_count; + =C2=A0 =C2=A0 =C2=A0while (register_count) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[register_count].= addr =3D start_address; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[register_count].= len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D start_address + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_count--; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc = (sizeof(uint32_t) * 2); + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_SP_REGNUM; + =C2=A0 =C2=A0} + =C2=A0else if (0x1E =3D=3D opcode1) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* BKPT insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* handle enhanced software breakpoint insn, BKPT. = =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* CPSR is changed to be executed in ARM state, =C2= =A0disabling normal + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 interrupts, entering abo= rt mode. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* accorindly to high vector configuration PC is set = accordingly. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0/* Oza: FIX ME ? =C2=A0what if user hit breakpoint an= d type reverse, in + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 that case, we need to go= back with previous CPSR and + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Program Counter.. =C2=A0= */ + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*3); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 2; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[2] =3D ARM_LR_REGNUM; + =C2=A0 =C2=A0 =C2=A0/* save SPSR also; how?. =C2=A0*/ + =C2=A0 =C2=A0} + =C2=A0else if ((0 =3D=3D opcode) || (1 =3D=3D opcode)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 /* ADD(5), ADD(6). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D reg_src1; + =C2=A0 =C2=A0} + =C2=A0else if (2 =3D=3D opcode) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* ADD(7), SUB(4). =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof= (uint32_t)*2); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D 1; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_SP_REGNUM; + =C2=A0 =C2=A0} + + + =C2=A0return 0; +} + +static int +thumb_handle_swi_insn (void *data) +{ + + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D (struct regcache*) thumb_insn_r->reg= cache; + + =C2=A0uint32_t reg_val1 =3D 0; + =C2=A0uint32_t reg_src1 =3D 0; + =C2=A0uint32_t opcode1 =3D 0, opcode2 =3D 0, register_bits =3D 0, registe= r_count =3D 0; + =C2=A0uint32_t register_list[8] =3D {0}, index =3D 0, start_address =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0opcode1 =3D bits (thumb_insn_r->arm_insn, 8, 12); + =C2=A0opcode2 =3D bits (thumb_insn_r->arm_insn, 11, 12); + + =C2=A0if (1 =3D=3D opcode2) + =C2=A0 =C2=A0{ + + =C2=A0 =C2=A0 =C2=A0/* LDMIA. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); + =C2=A0 =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + =C2=A0 =C2=A0 =C2=A0while (register_bits) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (register_bits & 0x00000001) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_list[register_count++] = =3D 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_bits =3D register_bits >> 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(sizeof(uint32_t= ) * (register_count + 2)); + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[0] =3D register_count += 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[register_count + 1] =3D= reg_src1; + =C2=A0 =C2=A0 =C2=A0for (register_count =3D 0; register_count < 8; regist= er_count++) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if =C2=A0(register_list[register_count]) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_regs[in= dex] =3D register_count; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0index++; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else if (0 =3D=3D opcode2) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* it handles both STMIA. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); + =C2=A0 =C2=A0 =C2=A0/* get Rn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); + =C2=A0 =C2=A0 =C2=A0GET_REG_VAL (reg_cache, reg_src1, &u_buf.buf[0]); + =C2=A0 =C2=A0 =C2=A0while (register_bits) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (register_bits & 0x00000001) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 register_count++; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_bits =3D register_bits >> 1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0start_address =3D u_buf.s_word; + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems =3D (struct arm_mem_r *)xmallo= c (sizeof(struct + =C2=A0 =C2=A0 =C2=A0arm_mem_r)*(register_count+1)); + =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[0].len =3D register_count; + =C2=A0 =C2=A0 =C2=A0while (register_count) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[register_count].= addr =3D start_address; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0thumb_insn_r->arm_mems[register_count].= len =3D 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0start_address =3D start_address + 4; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0register_count--; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else if (0x1F =3D=3D opcode1) + =C2=A0 =C2=A0 { + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* handle arm syscall insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (tdep->arm_swi_record !=3D NULL) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("handling syscall swi ins= n\n"); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tdep->arm_swi_record(reg_cache); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 =C2=A0 =C2=A0else + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0 } + + =C2=A0/* B(1), conditional branch is automatically taken care in process_= record, + =C2=A0 =C2=A0 =C2=A0 =C2=A0as PC is saved there. =C2=A0*/ + + =C2=A0return 0; +} + +static int +thumb_handle_branch_insn (void *data) +{ + =C2=A0insn_decode_record *thumb_insn_r =3D (insn_decode_record*) data; + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); + =C2=A0struct regcache *reg_cache =3D (struct regcache*) thumb_insn_r->reg= cache; + + =C2=A0uint32_t reg_val1=3D0; + =C2=A0uint32_t reg_src1=3D0; + =C2=A0uint32_t opcode =3D 0, immed_5 =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + + =C2=A0/* BL , BLX(1). =C2=A0*/ + =C2=A0thumb_insn_r->arm_regs =3D (uint32_t*)xmalloc (sizeof(uint32_t)*3); + =C2=A0thumb_insn_r->arm_regs[0] =3D 2; + =C2=A0thumb_insn_r->arm_regs[1] =3D ARM_PS_REGNUM; + =C2=A0thumb_insn_r->arm_regs[2] =3D ARM_LR_REGNUM; + + =C2=A0/* B(2) is automatically taken care in process_record, as PC is sav= ed + =C2=A0 =C2=A0 =C2=A0 =C2=A0there. =C2=A0*/ + =C2=A0return 0; +} + + + +static int +decode_insn (insn_decode_record *arm_record, uint32_t insn_size) +{ + + =C2=A0/* (starting from numerical 0); bits 25, 26, 27 decodes type of arm instruction. =C2=A0*/ + =C2=A0int (*const arm_handle_insn[NO_OF_TYPE_OF_ARM_INSNS]) (void*) =3D + =C2=A0{ + =C2=A0 =C2=A0 =C2=A0arm_handle_data_proc_misc_load_str_insn, =C2=A0/* 000= . =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_handle_data_proc_imm_insn, =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0/* 001. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_handle_ld_st_imm_offset_insn, =C2=A0 =C2=A0 =C2= =A0 =C2=A0 /* 010. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_handle_ld_st_reg_offset_insn, =C2=A0 =C2=A0 =C2= =A0 =C2=A0 /* 011. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_hamdle_ld_st_multiple_insn, =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 /* 100. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_handle_brn_insn, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 101. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_handle_coproc_insn, =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* 110. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0arm_handle_coproc_data_proc_insn =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0/* 111. =C2=A0*/ + =C2=A0}; + + =C2=A0/* (starting from numerical 0); bits 13,14,15 decodes type of thumb instruction. =C2=A0*/ + =C2=A0int (*const thumb_handle_insn[NO_OF_TYPE_OF_THUMB_INSNS]) (void*) = =3D + =C2=A0{ + =C2=A0 =C2=A0 =C2=A0thumb_handle_shift_add_sub_insn, =C2=A0 =C2=A0 =C2=A0= =C2=A0 /* 000. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_handle_add_sub_cmp_mov_insn, =C2=A0 =C2=A0 =C2= =A0 /* 001. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_handle_ld_st_reg_offset_insn, =C2=A0 =C2=A0 =C2= =A0/* 010. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_handle_ld_st_imm_offset_insn, =C2=A0 =C2=A0 =C2= =A0/* 011. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_hamdle_ld_st_stack_insn, =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 /* 100. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_handle_misc_insn, =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* 101. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_handle_swi_insn, =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* 110. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0thumb_handle_branch_insn =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* 111. =C2=A0*/ + =C2=A0}; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[insn_size]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0uint32_t ret=3D0; + + =C2=A0memset (&u_buf, 0, sizeof(u_buf)); + =C2=A0if (target_read_memory (arm_record->this_addr, &u_buf.buf[0], insn_= size)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0if (record_debug) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf_unfiltered (_("Process record: e= rror reading memory at " + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "addr %s len =3D %d.\n"), + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0paddress (arm_record->gdbarch, arm_reco= rd->this_addr), insn_size); + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0else if (ARM_INSN_SIZE_BYTES =3D=3D insn_size) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0arm_record->arm_insn =3D u_buf.s_word; + =C2=A0 =C2=A0 =C2=A0arm_record->cond =3D bits (arm_record->arm_insn, 28, = 31); + =C2=A0 =C2=A0 =C2=A0arm_record->id =3D bits (arm_record->arm_insn, 25, 27= ); + =C2=A0 =C2=A0 =C2=A0ret =3D (0x0F !=3D arm_record->cond)? \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_handle_insn[arm_record->id] = ((void*)arm_record) : \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0handle_extension_space(arm_recor= d); + =C2=A0 =C2=A0} + =C2=A0else if (THUMB_INSN_SIZE_BYTES =3D=3D insn_size) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0arm_record->arm_insn =3D u_buf.s_word; + =C2=A0 =C2=A0 =C2=A0arm_record->id =3D bits (arm_record->arm_insn, 13, 15= ); + =C2=A0 =C2=A0 =C2=A0ret =3D thumb_handle_insn[arm_record->id] ((void*)arm= _record); + =C2=A0 =C2=A0} + =C2=A0return ret; +} + +/* Parse the current instruction and record the values of the registers and + =C2=A0 memory that will be changed in current instruction to "record_arch= _list". + =C2=A0 Return -1 if something is wrong.. =C2=A0*/ + +int +arm_process_record (struct gdbarch *gdbarch, struct regcache *regcache, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 CORE_ADDR insn_addr) +{ + + =C2=A0enum bfd_endian byte_order =3D gdbarch_byte_order (gdbarch); + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); + =C2=A0uint32_t no_of_rec=3D0; + =C2=A0uint32_t ret=3D0; + =C2=A0ULONGEST t_bit =3D 0; + + =C2=A0union + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; + =C2=A0 =C2=A0} u_buf; + + =C2=A0insn_decode_record arm_record; + =C2=A0memset (&u_buf, 0, sizeof(u_buf)); + + =C2=A0memset (&arm_record, 0, sizeof (insn_decode_record)); + =C2=A0arm_record.regcache =3D regcache; + =C2=A0arm_record.this_addr =3D insn_addr; + =C2=A0arm_record.gdbarch =3D gdbarch; + + + =C2=A0if (record_debug > 1) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0fprintf_unfiltered (gdb_stdlog, "Process record: arm_= process_record " + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"addr =3D %s\n", + =C2=A0 =C2=A0 =C2=A0paddress (gdbarch, arm_record.this_addr)); + =C2=A0 =C2=A0} + + =C2=A0/* check the insn, whether it is thumb or arm one. =C2=A0*/ + + =C2=A0t_bit =3D arm_psr_thumb_bit (arm_record.gdbarch); + =C2=A0GET_REG_VAL (arm_record.regcache, ARM_PS_REGNUM, &u_buf.buf[0]); + + =C2=A0if (!(u_buf.s_word & t_bit)) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* we are decoding arm insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0ret =3D decode_insn (&arm_record, ARM_INSN_SIZE_BYTES= ); + =C2=A0 =C2=A0} + =C2=A0else + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0/* we are decoding thumb insn. =C2=A0*/ + =C2=A0 =C2=A0 =C2=A0ret =3D decode_insn (&arm_record, THUMB_INSN_SIZE_BYT= ES); + =C2=A0 =C2=A0} + + =C2=A0/* record registers. =C2=A0*/ + =C2=A0ARM_RECORD_ARCH_LIST_ADD_REG(ARM_PC_REGNUM); + =C2=A0if (arm_record.arm_regs) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0for (no_of_rec=3D1;no_of_rec<=3Darm_record.arm_regs[0= ];no_of_rec++) + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ARM_RECORD_ARCH_LIST_ADD_REG (arm_r= ecord.arm_regs[no_of_rec])) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D -1; + =C2=A0 =C2=A0 =C2=A0 =C2=A0} + =C2=A0 =C2=A0} + =C2=A0/* record memories. =C2=A0*/ + =C2=A0if (arm_record.arm_mems) + =C2=A0 =C2=A0{ + =C2=A0 =C2=A0 =C2=A0for (no_of_rec=3D1;no_of_rec<=3Darm_record.arm_mems[0= ].len;no_of_rec++) + =C2=A0 =C2=A0 =C2=A0 { + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (record_arch_list_add_mem \ + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((CORE_ADDR)arm_record.arm_mems[= no_of_rec].addr, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_record.arm_mems[no_of_rec].l= en)) + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D -1; + =C2=A0 =C2=A0 =C2=A0 } + =C2=A0 =C2=A0} + + =C2=A0if (record_arch_list_add_end ()) + =C2=A0 =C2=A0ret =3D -1; + + =C2=A0if (arm_record.arm_regs) + =C2=A0 =C2=A0xfree (arm_record.arm_regs); + =C2=A0if (arm_record.arm_mems) + =C2=A0 =C2=A0xfree (arm_record.arm_mems); + + =C2=A0return ret; +} diff -urN arm_orig/arm-tdep.h arm_new/arm-tdep.h --- arm_orig/arm-tdep.h =C2=A0 =C2=A02011-03-03 09:21:13.000000000 +0530 +++ arm_new/arm-tdep.h =C2=A0 =C2=A02011-04-15 13:11:15.000000000 +0530 @@ -200,6 +200,9 @@ =C2=A0 /* Return the expected next PC if FRAME is stopped at a syscall =C2=A0 =C2=A0 =C2=A0instruction. =C2=A0*/ =C2=A0 CORE_ADDR (*syscall_next_pc) (struct frame_info *frame); + + =C2=A0 /* Parse swi args. =C2=A0*/ + =C2=A0int (*arm_swi_record) (struct regcache *regcache); =C2=A0}; =C2=A0/* Structures used for displaced stepping. =C2=A0*/ @@ -310,6 +313,10 @@ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 struct displaced_step_closure *, =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 CORE_ADDR, CORE_ADDR, struct regcache *); +extern int arm_process_record (struct gdbarch *gdbarch, + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct regcache *regcache, CORE_ADDR = addr); + + =C2=A0/* Functions exported from armbsd-tdep.h. =C2=A0*/ =C2=A0/* Return the appropriate register set for the core section identified ----- Original Message ---- From: Yao Qi To: gdb@sourceware.org Sent: Mon, April 11, 2011 8:35:42 AM Subject: Re: [PATCH] arm reversible : progress On 04/10/2011 05:41 PM, paawan oza wrote: > Hi, > > phase2 (both arm and thumb insn implemenation is complete) > > Hi Tom: > I have taken care of most of your comments: but could nit incorporate num= ercial > > to be replaced by some meaningful symbolic names. > as I dont know what sort of symbolic names are approproate. > > This one looks much better than previous ones. =C2=A0Thanks for working on this. =C2=A0I am not the people to approve this patch. =C2=A0Some of my cen= ts below. > + > +#define ARM_INSN_SIZE_BYTES 4 > +#define THUMB_INSN_SIZE_BYTES 2 > +#define NO_OF_TYPE_OF_ARM_INSNS 8 > +#define NO_OF_TYPE_OF_THUMB_INSNS 8 > + > +#define ARM_RECORD_ARCH_LIST_ADD_REG(regnum) \ > + =C2=A0 =C2=A0record_arch_list_add_reg (arm_record.regcache, regnum) > + > +#define GET_REG_VAL(REGCACHE,NO,BUF) =C2=A0regcache_raw_read (REGCACHE, = NO, BUF); > + > +#define IS_IT_ARM_INSN(X) ((X & 0x00000020) >> 5) > +#define ARM_PARSE_INSN(X,BIT_POS,NO_OF_BITS) \ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((X >> (BIT_POS-= 1)) & (0xFFFFFFFF >> ((sizeof(uint32_t)*8) - \ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NO_OF_BIT= S))) There are some existing macros you can use for parsing instructions. /* Support routines for instruction parsing. =C2=A0*/ #define submask(x) ((1L << ((x) + 1)) - 1) #define bit(obj,st) (((obj) >> (st)) & 1) #define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) #define sbits(obj,st,fn) \ =C2=A0((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))= )) > + > +#define INSN_S_L_BIT_NUM 21 > +#define ARM_BIT_SET(X, NUM) (((X >> (NUM-1)) & 0x00000001) =3D=3D 1) > +#define GET_BIT(X, NUM) (((X >> (NUM-1)) & 0x00000001)) > + GET_BIT can be replaced by `bit' I posted above. > + > +static int > +handle_extension_space (insn_decode_record *arm_record) > +{ > + =C2=A0insn_decode_record *arm_insn_r =3D arm_record; > + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); > + =C2=A0struct regcache *reg_cache =3D arm_insn_r->regcache; > + > + =C2=A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0; > + =C2=A0uint32_t opcode1 =3D 0, opcode2 =3D 0; > + > + =C2=A0opcode1 =3D ARM_PARSE_INSN (arm_insn_r->arm_insn,26,3); > + =C2=A0if ((3 =3D=3D opcode1) && ARM_BIT_SET(arm_insn_r->arm_insn,5)) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* undefined instruction on ARM V5; need to handle = if later versions > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0define it. =C2=A0*/ > + =C2=A0 =C2=A0} > + > + =C2=A0opcode2 =3D ARM_PARSE_INSN (arm_insn_r->arm_insn,5,4); > + > + =C2=A0if ((!opcode1) && (9 =3D=3D opcode2)) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* handle arithmetic insn extension space. =C2=A0*/ > + =C2=A0 =C2=A0} > + > + =C2=A0opcode1 =3D ARM_PARSE_INSN (arm_insn_r->arm_insn,27,2); =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 ^ =C2=A0^ You need an extra space after each comma. > + =C2=A0opcode2 =3D ARM_PARSE_INSN (arm_insn_r->arm_insn,24,2); > + > + =C2=A0if ((!opcode1) && (2 =3D=3D opcode2) && !ARM_BIT_SET(arm_insn_r->= arm_insn,21)) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* handle control insn extension space. =C2=A0*/ > + =C2=A0 =C2=A0} > + > + =C2=A0opcode1 =3D ARM_PARSE_INSN (arm_insn_r->arm_insn,26,3); > + =C2=A0if ((!opcode1) && (ARM_BIT_SET(arm_insn_r->arm_insn,8)) \ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 && (ARM_BIT_SET= (arm_insn_r->arm_insn,5))) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* handle load/store insn extension space. =C2=A0*/ > + =C2=A0 =C2=A0} > + > + =C2=A0opcode1 =3D ARM_PARSE_INSN (arm_insn_r->arm_insn,24,5); > + =C2=A0if ((24 =3D=3D opcode1) && ARM_BIT_SET(arm_insn_r->arm_insn,22)) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* handle coprocessor insn extension space. =C2=A0*/ > + =C2=A0 =C2=A0} > + > + =C2=A0/* to be done for ARMv5 and later; as of now we return -1. =C2=A0= */ > + =C2=A0return -1; > +} > + > + > +/* Parse the current instruction and record the values of the registers = and > + =C2=A0 memory that will be changed in current instruction to "record_ar= ch_list". > + =C2=A0 Return -1 if something is wrong.. =C2=A0*/ > + > +int > +arm_process_record (struct gdbarch *gdbarch, struct regcache *regcache, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 CORE_ADDR insn_addr) > +{ > + > + =C2=A0enum bfd_endian byte_order =3D gdbarch_byte_order (gdbarch); > + =C2=A0struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); > + =C2=A0uint32_t no_of_rec=3D0; > + =C2=A0uint32_t ret=3D0; > + > + =C2=A0union > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0uint32_t s_word; > + =C2=A0 =C2=A0 =C2=A0gdb_byte buf[4]; > + =C2=A0 =C2=A0} u_buf; > + > + =C2=A0insn_decode_record arm_record; > + =C2=A0memset (&u_buf, 0, sizeof(u_buf)); > + > + =C2=A0memset (&arm_record, 0, sizeof (insn_decode_record)); > + =C2=A0arm_record.regcache =3D regcache; > + =C2=A0arm_record.this_addr =3D insn_addr; > + =C2=A0arm_record.gdbarch =3D gdbarch; > + > + > + =C2=A0if (record_debug > 1) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0fprintf_unfiltered (gdb_stdlog, "Process record: ar= m_process_record " > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"addr =3D %s\= n", > + =C2=A0 =C2=A0 =C2=A0paddress (gdbarch, arm_record.this_addr)); > + =C2=A0 =C2=A0} > + > + =C2=A0/* check the insn, whether it is thumb or arm one. =C2=A0*/ > + =C2=A0GET_REG_VAL (arm_record.regcache, ARM_PS_REGNUM, &u_buf.buf[0]); > + =C2=A0arm_record.cond =3D ARM_PARSE_INSN (arm_record.arm_insn,29,4); > + > + =C2=A0if (!IS_IT_ARM_INSN (u_buf.s_word)) Please reference to `arm_frame_is_thumb' or `displaced_in_arm_mode' to see how to check ARM mode or Thumb mode. > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* we are decoding arm insn. =C2=A0*/ > + =C2=A0 =C2=A0 =C2=A0ret =3D decode_insn (&arm_record, ARM_INSN_SIZE_BYT= ES); > + =C2=A0 =C2=A0} > + =C2=A0else > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0/* we are decoding thumb insn. =C2=A0*/ > + =C2=A0 =C2=A0 =C2=A0ret =3D decode_insn (&arm_record, THUMB_INSN_SIZE_B= YTES); On some ARM arch, there are 32-bit Thumb instructions, called Thumb-2. Do you plan to support Thumb-2 insn? > + =C2=A0 =C2=A0} > + > + =C2=A0/* record registers. =C2=A0*/ > + =C2=A0ARM_RECORD_ARCH_LIST_ADD_REG(ARM_PC_REGNUM); > + =C2=A0if (arm_record.arm_regs) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0for (no_of_rec=3D1;no_of_rec<=3Darm_record.arm_regs= [0];no_of_rec++) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (ARM_RECORD_ARCH_LIST_ADD_REG (arm= _record.arm_regs[no_of_rec])) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D -1; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0} > + =C2=A0/* record memories. =C2=A0*/ > + =C2=A0if (arm_record.arm_mems) > + =C2=A0 =C2=A0{ > + =C2=A0 =C2=A0 =C2=A0for (no_of_rec=3D1;no_of_rec<=3Darm_record.arm_mems= [0].len;no_of_rec++) > + =C2=A0 =C2=A0 =C2=A0 { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (record_arch_list_add_mem \ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0((CORE_ADDR)arm_record.arm_mem= s[no_of_rec].addr, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0arm_record.arm_mems[no_of_rec]= .len)) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D -1; > + =C2=A0 =C2=A0 =C2=A0 } > + =C2=A0 =C2=A0} > + > + =C2=A0if (record_arch_list_add_end ()) > + =C2=A0 =C2=A0ret =3D -1; > + > + =C2=A0if (arm_record.arm_regs) > + =C2=A0 =C2=A0xfree (arm_record.arm_regs); > + =C2=A0if (arm_record.arm_mems) > + =C2=A0 =C2=A0xfree (arm_record.arm_mems); > + > + =C2=A0return ret; > +} -- Yao (=E9=BD=90=E5=B0=A7)