From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28806 invoked by alias); 6 Jun 2011 17:42:19 -0000 Received: (qmail 28794 invoked by uid 22791); 6 Jun 2011 17:42:12 -0000 X-SWARE-Spam-Status: No, hits=1.5 required=5.0 tests=AWL,BAYES_40,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,RFC_ABUSE_POST,TW_EG,TW_NR,TW_SB,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nm9.bullet.mail.sp2.yahoo.com (HELO nm9.bullet.mail.sp2.yahoo.com) (98.139.91.79) by sourceware.org (qpsmtpd/0.43rc1) with SMTP; Mon, 06 Jun 2011 17:41:49 +0000 Received: from [98.139.91.68] by nm9.bullet.mail.sp2.yahoo.com with NNFMP; 06 Jun 2011 17:41:48 -0000 Received: from [98.139.91.9] by tm8.bullet.mail.sp2.yahoo.com with NNFMP; 06 Jun 2011 17:41:48 -0000 Received: from [127.0.0.1] by omp1009.mail.sp2.yahoo.com with NNFMP; 06 Jun 2011 17:41:48 -0000 Received: (qmail 98772 invoked by uid 60001); 6 Jun 2011 17:41:47 -0000 Message-ID: <427633.94615.qm@web36101.mail.mud.yahoo.com> Received: from [1.23.234.81] by web36101.mail.mud.yahoo.com via HTTP; Mon, 06 Jun 2011 10:41:47 PDT Date: Mon, 06 Jun 2011 17:42:00 -0000 From: chandra krishnappa Subject: Re: [PATCH] arm reversible : To: paawan oza , gdb-patches@sourceware.org In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 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-06/txt/msg00088.txt.bz2 Hi, I will be working for testing the patch of ARM reversible debugging feature= . Will be sending the test code for review once I develop the same. This is to inform that I will be working on this task, and anybody has any = pointers or comments to provide, its welcome. I will pick up the patch from here from the mailing list or will work with = Paawan Oza to get the latest build of arm reversible. Thanks & Regards, -Chandra K --- On Fri, 3/6/11, "paawan oza" wrote: > From: paawan oza > Date: Fri, Jun 3, 2011 at 1:21 PM > Subject: Re: [PATCH] arm reversible : > > To: Tom Tromey > Cc: gdb-patches@sourceware.org, > Petr Hluz=EDn >=20 >=20 > Hi Tom, >=20 > Fixed almost all comments. > any more comments are welcome make this patch ok, if ARM > person can have a look > at it it would be great. >=20 > PATCH STARTS > ------------------------------------diff -urN > arm_orig/arm-linux-tdep.c > arm_new/arm-linux-tdep.c > --- arm_orig/arm-linux-tdep.c =A0 =A02011-03-03 > 09:21:13.000000000 +0530 > +++ arm_new/arm-linux-tdep.c =A0 =A02011-05-07 > 14:20:31.000000000 +0530 > @@ -998,6 +998,9 @@ > =A0 set_gdbarch_fetch_tls_load_module_address (gdbarch, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 > =A0 =A0 =A0svr4_fetch_objfile_link_map); >=20 > + =A0/* Enable process record. =A0*/ > + =A0set_gdbarch_process_record (gdbarch, > arm_process_record); > + > =A0 tramp_frame_prepend_unwinder (gdbarch, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > &arm_linux_sigreturn_tramp_frame); > =A0 tramp_frame_prepend_unwinder (gdbarch, > @@ -1025,6 +1028,8 @@ >=20 >=20 > =A0 tdep->syscall_next_pc =3D arm_linux_syscall_next_pc; > + > + =A0tdep->arm_swi_record =3D NULL; > =A0} >=20 > =A0/* Provide a prototype to silence -Wmissing-prototypes. > =A0*/ > diff -urN arm_orig/arm-tdep.c arm_new/arm-tdep.c > --- arm_orig/arm-tdep.c =A0 =A02011-03-03 09:21:13.000000000 > +0530 > +++ arm_new/arm-tdep.c =A0 =A02011-06-03 13:16:35.000000000 > +0530 > @@ -54,6 +54,8 @@ > =A0#include "gdb_assert.h" > =A0#include "vec.h" >=20 > +#include "record.h" > + > =A0#include "features/arm-with-m.c" >=20 > =A0static int arm_debug; > @@ -7929,3 +7931,1763 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0NULL, /* FIXME: i18n: "ARM debugging > is %s. =A0*/ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0&setdebuglist, > &showdebuglist); > =A0} > + > + > + > +/* ARM-reversible process record data structures. =A0*/ > + > +#define ARM_INSN_SIZE_BYTES 4 > +#define THUMB_INSN_SIZE_BYTES 2 > +#define THUMB2_INSN_SIZE_BYTES 4 > + > +#define INSN_S_L_BIT_NUM 20 > + > +#define REG_ALLOC(REGS,LENGTH,RECORD_BUF) \ > +do =A0\ > + =A0{ \ > + =A0 =A0unsigned int reg_len =3D 0; reg_len =3D LENGTH; \ > + =A0 =A0if (reg_len) \ > + =A0 =A0 =A0{ \ > + =A0 =A0 =A0 =A0REGS =3D (uint32_t*) xmalloc (sizeof(uint32_t) * > (reg_len)); \ > + =A0 =A0 =A0 =A0while (reg_len) \ > + =A0 =A0 =A0 =A0 =A0{ \ > + =A0 =A0 =A0 =A0 =A0 =A0REGS[reg_len - 1] =3D RECORD_BUF[reg_len - > 1]; =A0\ > + =A0 =A0 =A0 =A0 =A0 =A0reg_len--; =A0\ > + =A0 =A0 =A0 =A0 =A0} \ > + =A0 =A0 =A0} \ > + =A0} \ > +while (0) > + > +#define MEM_ALLOC(MEMS,LENGTH,RECORD_BUF) \ > +do =A0\ > + =A0{ \ > + =A0 =A0unsigned int mem_len =3D 0; mem_len =3D LENGTH; \ > + =A0 =A0if (mem_len) \ > + =A0 =A0 =A0{ \ > + =A0 =A0 =A0 =A0MEMS =3D (struct arm_mem_r *)xmalloc \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 (sizeof(struct arm_mem_r) * > (mem_len)); \ > + =A0 =A0 =A0 =A0while (mem_len) \ > + =A0 =A0 =A0 =A0 =A0{ \ > + =A0 =A0 =A0 =A0 =A0 =A0MEMS[mem_len - 1].addr =3D > RECORD_BUF[(mem_len * 2) - 1]; \ > + =A0 =A0 =A0 =A0 =A0 =A0MEMS[mem_len - 1].len =3D > RECORD_BUF[(mem_len * 2) - 2]; \ > + =A0 =A0 =A0 =A0 =A0 =A0mem_len--; =A0 \ > + =A0 =A0 =A0 =A0 =A0} \ > + =A0 =A0 =A0} \ > + =A0} \ > +while (0) > + > + > +/* ARM memory record structure. =A0*/ > +struct arm_mem_r > +{ > + =A0uint32_t len; =A0 =A0 /* Record length. =A0*/ > + =A0CORE_ADDR addr; =A0 /* Memory address. =A0*/ > +}; > + > +/* ARM instruction record contains opcode of current insn > and execution state > (before entry to >=20 > +decode_insn() ), contains list of to-be-modified registers > and memory blocks > (on return from >=20 > +decode_insn() ). =A0*/ > +typedef struct insn_decode_record_t > +{ > + =A0struct gdbarch *gdbarch; > + =A0struct regcache *regcache; > + =A0CORE_ADDR this_addr; =A0 =A0 =A0 =A0 =A0/* Address of the > insn being decoded. =A0*/ > + =A0uint32_t arm_insn; =A0 =A0 =A0 =A0 =A0 =A0/* Should > accommodate thumb. =A0*/ > + =A0uint32_t cond; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Condition > code. =A0*/ > + =A0uint32_t opcode; =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Insn opcode. > =A0*/ > + =A0uint32_t decode; =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Insn decode > bits. =A0*/ > + =A0uint32_t mem_rec_count; =A0 =A0 =A0 /* No of mem recors > */ > + =A0uint32_t reg_rec_count; =A0 =A0 =A0 /* No of reg records > */ > + =A0uint32_t *arm_regs; =A0 =A0 =A0 =A0 =A0 /* Registers to be > saved for this record. =A0*/ > + =A0struct arm_mem_r *arm_mems; =A0 /* Memory to be saved > for this record. =A0*/ > +} insn_decode_record; > + > + > +/* Checks ARM SBZ and SBO mendatory fields. =A0*/ > + > +static int > +sbo_sbz (uint32_t insn, uint32_t bit_num, uint32_t len, > uint32_t sbo) > +{ > + =A0uint32_t ones =3D bits (insn, bit_num - 1, (bit_num -1) + > (len - 1)); > + > + =A0if (!len) > + =A0 =A0return 1; > + > + =A0if(!sbo) > + =A0 =A0ones =3D ~ones; > + > + =A0while (ones) > + =A0 =A0{ > + =A0 =A0 =A0if (!(ones & sbo)) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0return 0; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0ones =3D ones >> 1; > + =A0 =A0} > + =A0return 1; > +} > + > +/* Handling ARM extension space insns. =A0*/ > + > +static int > +handle_extension_space (insn_decode_record *arm_insn_r) > +{ > + =A0uint32_t ret =3D 0; > + =A0uint32_t opcode1 =3D 0, opcode2 =3D 0; > + > + =A0opcode1 =3D bits (arm_insn_r->arm_insn, 25, 27); > + =A0if ((3 =3D=3D opcode1) && (bit > (arm_insn_r->arm_insn, 4))) > + =A0 =A0{ > + =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0/* Undefined instruction on ARM V5; need to > handle if later versions > + =A0 =A0 =A0 =A0 =A0define it. =A0*/ > + =A0 =A0} > + > + =A0opcode2 =3D bits (arm_insn_r->arm_insn, 4, 7); > + > + =A0if ((!opcode1) && (9 =3D=3D opcode2)) > + =A0 =A0{ > + =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0/* Handle arithmetic insn extension space. =A0*/ > + =A0 =A0} > + > + =A0opcode1 =3D bits (arm_insn_r->arm_insn, 26, 27); > + =A0opcode2 =3D bits (arm_insn_r->arm_insn, 23, 24); > + > + =A0if ((!opcode1) && (2 =3D=3D opcode2) && > (!bit (arm_insn_r->arm_insn, 20))) > + =A0 =A0{ > + =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0/* Handle control insn extension space. =A0*/ > + =A0 =A0} > + > + =A0opcode1 =3D bits (arm_insn_r->arm_insn, 25, 27); > + =A0if ((!opcode1) && (bit > (arm_insn_r->arm_insn, 7)) \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 && > (bit(arm_insn_r->arm_insn, 4))) > + =A0 =A0{ > + =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0/* Handle load/store insn extension space. =A0*/ > + =A0 =A0} > + > + =A0opcode1 =3D bits (arm_insn_r->arm_insn, 23, 27); > + =A0if ((24 =3D=3D opcode1) && (bit > (arm_insn_r->arm_insn, 21))) > + =A0 =A0{ > + =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0/* Handle coprocessor insn extension space. =A0*/ > + =A0 =A0} > + > + =A0/* To be done for ARMv5 and later; as of now we return > -1. =A0*/ > + =A0if (-1 =3D=3D ret) > + =A0 =A0printf_unfiltered (_("Process record does not > support instruction 0x%0x " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "at address %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > arm_insn_r->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress > (arm_insn_r->gdbarch, arm_insn_r->this_addr)); > + =A0return ret; > +} > + > +/* Handling opcode 000 insns. =A0*/ > + > +static int > +arm_handle_data_proc_misc_ld_str_insn (insn_decode_record > *arm_insn_r) > +{ > + =A0struct regcache *reg_cache =3D arm_insn_r->regcache; > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf[2]; > + > + > + =A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0, reg_dest =3D 0; > + =A0uint32_t immed_high =3D 0, immed_low =3D 0,offset_8 =3D 0, > tgt_mem_addr =3D 0; > + =A0uint32_t opcode1 =3D 0; > + > + =A0memset(&u_buf, 0, sizeof (u_buf)); > + > + =A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, > 21, 24); > + =A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, > 4, 7); > + =A0opcode1 =3D bits (arm_insn_r->arm_insn, 20, 24); > + > + =A0/* Data processing insn /multiply insn. =A0*/ > + =A0if ((9 =3D=3D arm_insn_r->decode) > + =A0 =A0 && (((4 <=3D arm_insn_r->opcode) > && (7 >=3D arm_insn_r->opcode)) > + =A0 =A0 || =A0((0 =3D=3D arm_insn_r->opcode) || (1 =3D=3D > arm_insn_r->opcode)))) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle multiply instructions. =A0*/ > + =A0 =A0 =A0/* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL. =A0*/ > + =A0 =A0 =A0 =A0if ((0 =3D=3D arm_insn_r->opcode) || (1 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0/* Handle MLA and MUL. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0record_buf[0] =3D bits > (arm_insn_r->arm_insn, 16, 19); > + =A0 =A0 =A0 =A0 =A0 =A0record_buf[1] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else if ((4 <=3D arm_insn_r->opcode) > && (7 >=3D arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0/* Handle SMLAL, SMULL, UMLAL, UMULL. =A0*/ > + =A0 =A0 =A0 =A0 =A0 record_buf[0] =3D bits > (arm_insn_r->arm_insn, 16, 19); > + =A0 =A0 =A0 =A0 =A0 record_buf[1] =3D bits > (arm_insn_r->arm_insn, 12, 15); > + =A0 =A0 =A0 =A0 =A0 record_buf[2] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0 arm_insn_r->reg_rec_count =3D 3; > + =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0} > + =A0else if ((bit (arm_insn_r->arm_insn, > INSN_S_L_BIT_NUM)) > + =A0 =A0 =A0 =A0&& ((11 =3D=3D arm_insn_r->decode) || > (13 =3D=3D arm_insn_r->decode))) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* Handle misc load insns, as 20th bit (L =3D > 1). =A0*/ > + =A0 =A0 =A0 =A0/* LDR insn has a capability to do branching, > if > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0MOV LR, PC is preccedded by LDR > insn having Rn as R15 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0in that case, it emulates > branch and link insn, and hence we > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0need to save CSPR and PC as > well. I am not sure this is right >=20 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0place as opcode =3D 010 LDR insn > make this happen, if R15 was > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0used. =A0*/ > + =A0 =A0 =A0 =A0reg_dest =3D bits (arm_insn_r->arm_insn, 12, > 15); > + =A0 =A0 =A0 =A0if (15 !=3D reg_dest) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0record_buf[0] =3D bits > (arm_insn_r->arm_insn, 12, 15); > + =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_dest; > + =A0 =A0 =A0 =A0 =A0 =A0record_buf[1] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0} > + =A0else if (((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0&& (sbo_sbz (arm_insn_r->arm_insn, 5, > 12, 0)) > + =A0 =A0 =A0&& (sbo_sbz (arm_insn_r->arm_insn, 13, > 4, 1)) > + =A0 =A0 =A0&& (2 =3D=3D bits (arm_insn_r->arm_insn, > 20, 21))) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle MSR insn. =A0*/ > + =A0 =A0 =A0if (9 =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* CSPR is going to be changed. =A0*/ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* SPSR is going to be changed. */ > + =A0 =A0 =A0 =A0 =A0/* How to read SPSR value ? =A0*/ > + =A0 =A0 =A0 =A0 =A0printf_unfiltered (_("Process record does > not support instruction " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "0x%0x at > address %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > arm_insn_r->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress > (arm_insn_r->gdbarch, > arm_insn_r->this_addr)); > + =A0 =A0 =A0 =A0 =A0return -1; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if ((9 =3D=3D arm_insn_r->decode) > + =A0 =A0 =A0 =A0 =A0 && ((8 =3D=3D arm_insn_r->opcode) > || (10 =3D=3D arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0 && (!bit (arm_insn_r->arm_insn, > =A0INSN_S_L_BIT_NUM))) > + =A0 =A0{ > + =A0 =A0 =A0/* Handling SWP, SWPB. =A0*/ > + =A0 =A0 =A0/* These insns, changes register and memory as > well. =A0*/ > + =A0 =A0 =A0/* SWP or SWPB insn. =A0*/ > + =A0 =A0 =A0/* Get memory address given by Rn. =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, > 19); > + =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[0].unsigned_regval); > + =A0 =A0 =A0/* SWP insn ?, swaps word. =A0*/ > + =A0 =A0 =A0if (8 =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 4; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* SWPB insn, swaps only byte. =A0*/ > + =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0record_buf_mem[1] =3D u_buf[0].unsigned_regval; > + =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 12, 15); > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if ((3 =3D=3D arm_insn_r->decode) && (0x12 > =3D=3D opcode1) > + =A0 =A0 =A0 =A0 =A0 && (sbo_sbz > (arm_insn_r->arm_insn, 9, 12, 1))) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle BLX, branch and link/exchange. =A0*/ > + =A0 =A0 =A0if (9 =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* Branch is chosen by setting T bit of CSPR, > bitp[0] of Rm, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 and R14 stores the return > address. =A0*/ > + =A0 =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0record_buf[1] =3D ARM_LR_REGNUM; > + =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0} > + =A0 =A0} > + =A0else if ((7 =3D=3D arm_insn_r->decode) && (0x12 > =3D=3D opcode1)) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle enhanced software breakpoint insn, BKPT > */ > + =A0 =A0 =A0/* CPSR is changed to be executed in ARM state, > =A0disabling normal > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts, entering abort mode. > =A0*/ > + =A0 =A0 =A0/* Accorindly to high vector configuration PC is > set accordingly */ > + =A0 =A0 =A0/* What if user hit breakpoint and type reverse, > in > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 that case, we need to go back with > previous CPSR and > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 Program Counter. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0record_buf[1] =3D ARM_LR_REGNUM; > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + > + =A0 =A0 =A0/* Save SPSR also; how? =A0*/ > + =A0 =A0 =A0printf_unfiltered (_("Process record does not > support instruction " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "0x%0x at address > %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > arm_insn_r->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0paddress > (arm_insn_r->gdbarch, arm_insn_r->this_addr)); > + =A0 =A0 =A0return -1; > + =A0 =A0} > + =A0else if ((11 =3D=3D arm_insn_r->decode) > + =A0 =A0 =A0 =A0 =A0&& (!bit (arm_insn_r->arm_insn, > INSN_S_L_BIT_NUM))) > + =A0{ > + =A0 =A0/* Handle enhanced store insns and DSP insns (e.g. > LDRD) > + =A0 =A0 =A0 =A0 =A0 let us begin according to addressing modes > for store insns > + =A0 =A0 =A0 =A0 =A0 STRH insn, addresing modes are taken > following. =A0*/ > + =A0 =A0if ((14 =3D=3D arm_insn_r->opcode) || (10 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* 1) Handle misc store, immediate offset. > =A0*/ > + =A0 =A0 =A0 =A0immed_low =3D bits (arm_insn_r->arm_insn, 0, > 3); > + =A0 =A0 =A0 =A0immed_high =3D bits (arm_insn_r->arm_insn, 8, > 11); > + =A0 =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, > 19); > + =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0if (15 =3D=3D reg_src1) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0/* If R15 was used as Rn, hence current > PC+8. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0u_buf[0].unsigned_regval =3D > u_buf[0].unsigned_regval + 8; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0offset_8 =3D (immed_high << 4) | > immed_low; > + =A0 =A0 =A0 =A0/* Calculate target store address. =A0*/ > + =A0 =A0 =A0 =A0if (14 =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[0].unsigned_regval > + offset_8; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[0].unsigned_regval > - offset_8; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0record_buf_mem[0] =3D 2; > + =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + =A0 =A0 =A0} > + =A0 =A0else if ((12 =3D=3D arm_insn_r->opcode) || (8 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* 2) Store, register offset. =A0*/ > + =A0 =A0 =A0 =A0/* Get Rm. =A0*/ > + =A0 =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 0, > 3); > + =A0 =A0 =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0 =A0 =A0reg_src2 =3D bits (arm_insn_r->arm_insn, 16, > 19); > + =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src2 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[1].unsigned_regval); >=20 > + =A0 =A0 =A0 =A0if (15 =3D=3D reg_src2) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0/* If R15 was used as Rn, hence current > PC+8. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0u_buf[0].unsigned_regval =3D > u_buf[0].unsigned_regval + 8; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0/* Calculate target store address, Rn +/- Rm, > register offset. =A0*/ > + =A0 =A0 =A0 =A0if (12 =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[0].unsigned_regval > + u_buf[1].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[1].unsigned_regval > - u_buf[0].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0record_buf_mem[0] =3D 2; > + =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + =A0 =A0 =A0} > + =A0 =A0else if ((11 =3D=3D arm_insn_r->opcode) || (15 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (2 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* 3) Store, immediate pre-indexed. =A0*/ > + =A0 =A0 =A0 =A0/* 5) Store, immediate post-indexed. =A0*/ > + =A0 =A0 =A0 =A0immed_low =3D bits (arm_insn_r->arm_insn, 0, > 3); > + =A0 =A0 =A0 =A0immed_high =3D bits (arm_insn_r->arm_insn, 8, > 11); > + =A0 =A0 =A0 =A0offset_8 =3D (immed_high << 4) | > immed_low; > + =A0 =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, > 19); > + =A0 =A0 =A0 =A0regcache_raw_read_unsigned(reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 , > &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0/* Calculate target store address, Rn +/- Rm, > register offset. =A0*/ > + =A0 =A0 =A0 =A0if ((15 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[0].unsigned_regval > + offset_8; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[0].unsigned_regval > - offset_8; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0record_buf_mem[0] =3D 2; > + =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + =A0 =A0 =A0 =A0/* Record Rn also as it changes. =A0*/ > + =A0 =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 16, 19); > + =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0} > + =A0 =A0else if ((9 =3D=3D arm_insn_r->opcode) || (13 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (0 =3D=3D arm_insn_r->opcode) || (4 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* 4) Store, register pre-indexed. =A0*/ > + =A0 =A0 =A0 =A0/* 6) Store, register post -indexed. =A0*/ > + =A0 =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 0, > 3); > + =A0 =A0 =A0 =A0reg_src2 =3D bits (arm_insn_r->arm_insn, 16, > 19); > + =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src2 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[1].unsigned_regval); > + =A0 =A0 =A0 =A0/* Calculate target store address, Rn +/- Rm, > register offset. =A0*/ > + =A0 =A0 =A0 =A0if ((13 =3D=3D arm_insn_r->opcode) || (4 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[0].unsigned_regval > + u_buf[1].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf[1].unsigned_regval > - u_buf[0].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0record_buf_mem[0] =3D 2; > + =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + =A0 =A0 =A0 =A0/* Record Rn also as it changes. =A0*/ > + =A0 =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 16, 19); > + =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0} > + =A0 =A0/* DSP insns (e.g. LDRD) =A0TBD. =A0*/ > + =A0} > + =A0else if ((1 =3D=3D arm_insn_r->decode) && (0x12 > =3D=3D opcode1) > + =A0 =A0 =A0 =A0 =A0 && sbo_sbz > (arm_insn_r->arm_insn, 9, 12, 1)) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle BX, branch and link/exchange. =A0*/ > + =A0 =A0 =A0/* Branch is chosen by setting T bit of CSPR, > bitp[0] of Rm. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if ((1 =3D=3D arm_insn_r->decode) && (0x16 > =3D=3D opcode1) > + =A0 =A0 =A0 =A0 =A0 && (sbo_sbz > (arm_insn_r->arm_insn, 9, 4, 1)) > + =A0 =A0 =A0 =A0 =A0 && (sbo_sbz > (arm_insn_r->arm_insn, 17, 4, 1))) > + =A0 =A0{ > + =A0 =A0 =A0/* Count leading zeros: CLZ. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 12, 15); > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if ((!bit (arm_insn_r->arm_insn, > INSN_S_L_BIT_NUM)) > + =A0 =A0 =A0 =A0 =A0&& ((8 =3D=3D arm_insn_r->opcode) || > (10 =3D=3D arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0&& (sbo_sbz > (arm_insn_r->arm_insn, 17, 4, 1)) > + =A0 =A0 =A0 =A0 =A0&& (sbo_sbz > (arm_insn_r->arm_insn, 1, 12, 0)) > + =A0 =A0 =A0 =A0 =A0) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle MRS insn. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 12, 15); > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if (arm_insn_r->opcode <=3D 15) > + =A0 =A0{ > + =A0 =A0 =A0/* Normal data processing insns. =A0*/ > + =A0 =A0 =A0/* Out of 11 shifter operands mode, all the insn > modifies destination > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0register, which is specified by > 13-16 decode. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 12, 15); > + =A0 =A0 =A0record_buf[1] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0gdb_assert_not_reached ("no decoding pattern > found"); > + =A0 =A0} > + > + =A0REG_ALLOC (arm_insn_r->arm_regs, > arm_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (arm_insn_r->arm_mems, > arm_insn_r->mem_rec_count, record_buf_mem); > + =A0return 0; > +} > + > +/* Handling opcode 001 insns. =A0*/ > + > +static int > +arm_handle_data_proc_imm_insn (insn_decode_record > *arm_insn_r) > +{ > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, > 21, 24); > + =A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, > 4, 7); > + > + =A0if (((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 && (2 =3D=3D bits (arm_insn_r->arm_insn, > 20, 21)) > + =A0 =A0 =A0 && (sbo_sbz (arm_insn_r->arm_insn, > 13, 4, 1)) > + =A0 =A0 =A0 ) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle MSR insn. =A0*/ > + =A0 =A0 =A0if (9 =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/*CSPR is going to be changed. =A0*/ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 /* SPSR is going to be changed. =A0*/ > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if (arm_insn_r->opcode <=3D 15) > + =A0 =A0{ > + =A0 =A0 =A0/* Normal data processing insns. =A0*/ > + =A0 =A0 =A0/* Out of 11 shifter operands mode, all the insn > modifies destination > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0register, which is specified by > 13-16 decode. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D bits (arm_insn_r->arm_insn, > 12, 15); > + =A0 =A0 =A0record_buf[1] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0gdb_assert_not_reached ("no decoding pattern > found"); > + =A0 =A0} > + > + =A0REG_ALLOC (arm_insn_r->arm_regs, > arm_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (arm_insn_r->arm_mems, > arm_insn_r->mem_rec_count, record_buf_mem); > + =A0return 0; > +} > + > +/* Handling opcode 010 insns. =A0*/ > + > +static int > +arm_handle_ld_st_imm_offset_insn (insn_decode_record > *arm_insn_r) > +{ > + =A0struct regcache *reg_cache =3D arm_insn_r->regcache; > + > + =A0uint32_t reg_src1 =3D 0 , reg_dest =3D 0; > + =A0uint32_t offset_12 =3D 0, tgt_mem_addr =3D 0; > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0memset(&u_buf, 0, sizeof (u_buf)); > + =A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, > 21, 24); > + =A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, > 4, 7); > + > + =A0if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > + =A0 =A0{ > + =A0 =A0 =A0reg_dest =3D bits (arm_insn_r->arm_insn, 12, > 15); > + =A0 =A0 =A0/* LDR insn has a capability to do branching, if > + =A0 =A0 =A0 =A0 =A0 =A0 =A0MOV LR, PC is precedded by LDR insn > having Rn as R15 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0in that case, it emulates branch and > link insn, and hence we > + =A0 =A0 =A0 =A0 =A0 =A0 =A0need to save CSPR and PC as well. > =A0*/ > + =A0 =A0 =A0if (15 !=3D reg_dest) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D bits > (arm_insn_r->arm_insn, 12, 15); > + =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_dest; > + =A0 =A0 =A0 =A0 =A0record_buf[1] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0if ((8 =3D=3D arm_insn_r->opcode) || (10 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (12 =3D=3D arm_insn_r->opcode) || (14 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* Store, immediate offset, immediate > pre-indexed, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0immediate post-indexed. > =A0*/ > + =A0 =A0 =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, > 16, 19); > + =A0 =A0 =A0 =A0 =A0offset_12 =3D bits (arm_insn_r->arm_insn, > 0, 11); > + =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0, > &u_buf.unsigned_regval); > + =A0 =A0 =A0 =A0 =A0/* U =3D=3D 1 */ > + =A0 =A0 =A0 =A0 =A0if (bit (arm_insn_r->arm_insn, 23)) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D u_buf.unsigned_regval > + offset_12; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 tgt_mem_addr =3D u_buf.unsigned_regval - > offset_12; > + =A0 =A0 =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0 =A0switch(arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 8: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 12: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 9: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 13: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 1: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 5: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* STR insn, STRT insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 10: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 14: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 11: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 15: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 3: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0case 7: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* STRB insn, STRBT insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0default: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gdb_assert_not_reached ("Invalid > addressing mode for insn"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + > + =A0 =A0 =A0 =A0 =A0if ((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0|| (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0/* We are handling pre-indexed mode; > post-indexed mode; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 where Rn is > going to be changed. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + > + =A0REG_ALLOC (arm_insn_r->arm_regs, > arm_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (arm_insn_r->arm_mems, > arm_insn_r->mem_rec_count, record_buf_mem); > + =A0return 0; > +} > + > +/* Handling opcode 011 insns. =A0*/ > + > +static int > +arm_handle_ld_st_reg_offset_insn (insn_decode_record > *arm_insn_r) > +{ > + =A0struct regcache *reg_cache =3D arm_insn_r->regcache; > + > + =A0uint32_t shift_imm =3D 0; > + =A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0, reg_dest =3D 0; > + =A0uint32_t immed_high =3D 0, immed_low =3D 0, offset_12 =3D 0, > tgt_mem_addr =3D 0; > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0LONGEST signed_word; > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf[2]; > + > + =A0memset(&u_buf, 0, sizeof (u_buf)); > + =A0arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, > 21, 24); > + =A0arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, > 4, 7); > + > + =A0/* Handle enhanced store insns and LDRD DSP insn, > + =A0 =A0 =A0 =A0let us begin according to addressing modes for > store insns > + =A0 =A0 =A0 =A0STRH insn. =A0*/ > + > + =A0/* LDR or STR? =A0*/ > + =A0if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > + =A0 =A0{ > + =A0 =A0 =A0reg_dest =3D bits (arm_insn_r->arm_insn, 12, > 15); > + =A0 =A0 =A0/* LDR insn has a capability to do branching, if > + =A0 =A0 =A0 =A0 =A0 =A0 =A0MOV LR, PC is precedded by LDR insn > having Rn as R15 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0in that case, it emulates branch and > link insn, and hence we > + =A0 =A0 =A0 =A0 =A0 =A0 =A0need to save CSPR and PC as well. > =A0*/ > + =A0 =A0 =A0if (15 !=3D reg_dest) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D bits > (arm_insn_r->arm_insn, 12, 15); > + =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_dest; > + =A0 =A0 =A0 =A0 =A0record_buf[1] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0if ((8 =3D=3D arm_insn_r->opcode) || (10 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (12 =3D=3D arm_insn_r->opcode) || (14 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D > arm_insn_r->opcode) > + =A0 =A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0if (! bits (arm_insn_r->arm_insn, 4, 11)) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0/* Store insn, register offset and > register pre-indexed, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0register > post-indexed. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0/* Get Rm. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0reg_src1 =3D bits > (arm_insn_r->arm_insn, 0, 3); > + =A0 =A0 =A0 =A0 =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0reg_src2 =3D bits > (arm_insn_r->arm_insn, 16, 19); > + =A0 =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0, &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src2 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0, > &u_buf[1].unsigned_regval); >=20 > + =A0 =A0 =A0 =A0 =A0 =A0if (15 =3D=3D reg_src2) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* If R15 was used as Rn, hence > current PC+8. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Pre-indexed mode doesnt reach > here ; illegal insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0u_buf[0].unsigned_regval =3D > u_buf[0].unsigned_regval + 8; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0/* Calculate target store address, Rn > +/- Rm, register offset. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0/* U =3D=3D 1. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0if (bit (arm_insn_r->arm_insn, 23)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D > u_buf[0].unsigned_regval + > u_buf[1].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D > u_buf[1].unsigned_regval - > u_buf[0].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0 =A0 =A0switch(arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 8: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 12: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 9: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 13: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 1: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 5: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* STR insn, STRT insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 10: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 14: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 11: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 15: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 3: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 7: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* STRB insn, STRBT insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0default: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gdb_assert_not_reached > ("Invalid addressing mode for insn"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + > + =A0 =A0 =A0 =A0 =A0 =A0if ((9 =3D=3D arm_insn_r->opcode) || (11 > =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (13 =3D=3D arm_insn_r->opcode) || (15 > =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Rn is going to be changed in > pre-indexed mode and > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0post-indexed mode as well. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_src2; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0/* Store insn, scaled register offset; > scaled pre-indexed. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D bits > (arm_insn_r->arm_insn, 5, 6); > + =A0 =A0 =A0 =A0 =A0 =A0/* Get Rm. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0reg_src1 =3D bits > (arm_insn_r->arm_insn, 0, 3); > + =A0 =A0 =A0 =A0 =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0reg_src2 =3D bits > (arm_insn_r->arm_insn, 16, 19); > + =A0 =A0 =A0 =A0 =A0 =A0/* Get shift_imm. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0shift_imm =3D bits > (arm_insn_r->arm_insn, 7, 11); > + =A0 =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0, &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0 =A0regcache_raw_read_signed (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0, &u_buf[0].signed_word); > + =A0 =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src2 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0, &u_buf[1].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0 =A0/* Offset_12 used as shift. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0switch(offset_12) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 0: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Offset_12 used as index. > =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D > u_buf[0].unsigned_regval << shift_imm; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 1: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D > (!shift_imm)?0:u_buf[0].unsigned_regval >> > shift_imm; >=20 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 2: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (!shift_imm) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (bit > (u_buf[0].unsigned_regval, 31)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D > 0xFFFFFFFF; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D 0; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* This is arithmetic > shift. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D > u_buf[0].signed_word >> shift_imm; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 3: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (!shift_imm) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0regcache_raw_read_unsigned (reg_cache, ARM_PS_REGNUM > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0 =A0 =A0 =A0 =A0 =A0, &u_buf[1].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Get C flag value and > shift it by 31. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D (((bit > (u_buf[1].unsigned_regval, 29)) << 31) > \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| > (u_buf[0].unsigned_regval) >> 1); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset_12 =3D > (u_buf[0].unsigned_regval >> shift_imm) \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 | > (u_buf[0].unsigned_regval << (sizeof(uint32_t) - > shift_imm)); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0default: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gdb_assert_not_reached > ("Invalid addressing mode for insn"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src2 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0, &u_buf[1].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0 =A0/* U =3D=3D 1 */ > + =A0 =A0 =A0 =A0 =A0 =A0if (bit (arm_insn_r->arm_insn, 23)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D > u_buf[1].unsigned_regval + offset_12; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0tgt_mem_addr =3D > u_buf[1].unsigned_regval - offset_12; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0 =A0 =A0 =A0switch (arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 8: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 12: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 9: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 13: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 1: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 5: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* STR insn, STRT insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 10: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 14: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 11: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 15: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 3: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0case 7: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* STRB insn, STRBT insn. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0default: > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0gdb_assert_not_reached > ("Invalid addressing mode for insn"); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[1] =3D tgt_mem_addr; > + =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D 1; > + > + =A0 =A0 =A0 =A0 =A0 =A0if ((9 =3D=3D arm_insn_r->opcode) || (11 > =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (13 =3D=3D arm_insn_r->opcode) || (15 > =3D=3D arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D > arm_insn_r->opcode) > + =A0 =A0 =A0 =A0 =A0 =A0|| (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D > arm_insn_r->opcode)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Rn is going to be changed in > register scaled pre-indexed > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mode, and > scaled post indexed mode. =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_src2; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0} > + =A0 =A0} > + > + =A0REG_ALLOC (arm_insn_r->arm_regs, > arm_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (arm_insn_r->arm_mems, > arm_insn_r->mem_rec_count, record_buf_mem); > + =A0return 0; > +} > + > +/* Handling opcode 100 insns. =A0*/ > + > +static int > +arm_handle_ld_st_multiple_insn (insn_decode_record > *arm_insn_r) > +{ > + =A0struct regcache *reg_cache =3D arm_insn_r->regcache; > + > + =A0uint32_t register_list[16] =3D {0}, register_count =3D 0, > register_bits =3D 0; >=20 >=20 > + =A0uint32_t shift_imm =3D 0; > + =A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0, addr_mode =3D 0, > no_of_regs =3D 0; > + =A0uint32_t start_address =3D 0, index =3D 0; > + =A0uint32_t record_buf[24], record_buf_mem[48]; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf[2]; > + > + =A0memset (&u_buf, 0, sizeof(u_buf)); > + > + =A0/* This mode is exclusively for load and store > multiple. =A0*/ > + =A0/* Handle incremenrt after/before and decrment > after.before mode; > + =A0 =A0 =A0 =A0Rn is changing depending on W bit, but as of > now we store Rn too > without optmization. =A0*/ > + > + =A0if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > + =A0 =A0{ > + =A0 =A0 =A0/* LDM (1,2,3) where LDM (3) changes CPSR too. > =A0*/ > + > + =A0 =A0 =A0if ((bit (arm_insn_r->arm_insn,20)) && > !(bit (arm_insn_r->arm_insn,22))) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0register_bits =3D bits > (arm_insn_r->arm_insn, 0, 15); > + =A0 =A0 =A0 =A0 =A0no_of_regs =3D 15; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0register_bits =3D bits > (arm_insn_r->arm_insn, 0, 14); > + =A0 =A0 =A0 =A0 =A0no_of_regs =3D 14; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, > 19); > + =A0 =A0 =A0while (register_bits) > + =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 if (register_bits & 0x00000001) > + =A0 =A0 =A0 =A0 =A0 register_list[register_count++] =3D 1; > + =A0 =A0 =A0 =A0 register_bits =3D register_bits >> 1; > + =A0 =A0 =A0 } > + > + =A0 =A0 =A0 =A0/* Extra space for Base Register and CPSR; > wihtout optmization. =A0*/ > + =A0 =A0 =A0 =A0record_buf[register_count] =3D reg_src1; > + =A0 =A0 =A0 =A0record_buf[register_count + 1] =3D > ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0arm_insn_r->reg_rec_count =3D register_count > + 2; > + > + =A0 =A0 =A0 =A0for (register_count =3D 0; register_count < > no_of_regs; register_count++) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0if =A0(register_list[register_count]) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Register_count gives total no of > registers and dually working > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 as reg number. > =A0*/ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf[index] =3D > register_count; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0index++; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0 =A0} > + > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0/* It handles both STM(1) and STM(2). =A0*/ > + =A0 =A0addr_mode =3D bits (arm_insn_r->arm_insn, 23, 24); > + > + =A0 =A0register_bits =3D bits (arm_insn_r->arm_insn, 0, > 15); > + =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > + =A0 =A0regcache_raw_read_unsigned (reg_cache, reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf[0].unsigned_regval); > + =A0 =A0while (register_bits) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0if (register_bits & 0x00000001) > + =A0 =A0 =A0 =A0 =A0 register_count++; > + =A0 =A0 =A0 =A0register_bits =3D register_bits >> 1; > + =A0 =A0 =A0} > + > + =A0 =A0switch(addr_mode) > + =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0/* Decrement after. =A0*/ > + =A0 =A0 =A0 =A0case 0: > + =A0 =A0 =A0 =A0 =A0start_address =3D (u_buf[0].unsigned_regval) > - (register_count * 4) + > 4; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D > register_count; > + =A0 =A0 =A0 =A0 =A0while (register_count) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 1] =3D start_address; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 2] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0start_address =3D start_address + 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0register_count--; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0/* Increment after. =A0*/ > + =A0 =A0 =A0 =A0case 1: > + =A0 =A0 =A0 =A0 =A0start_address =3D u_buf[0].unsigned_regval; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D > register_count; > + =A0 =A0 =A0 =A0 =A0while (register_count) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 1] =3D start_address; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 2] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0start_address =3D start_address + 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0register_count--; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0/* Decrement before. =A0*/ > + =A0 =A0 =A0 =A0case 2: > + > + =A0 =A0 =A0 =A0 =A0start_address =3D (u_buf[0].unsigned_regval) > - (register_count * 4); > + =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D > register_count; > + =A0 =A0 =A0 =A0 =A0while (register_count) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 1] =3D start_address; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 2] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0start_address =3D start_address + 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0register_count--; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0/* Increment before. =A0*/ > + =A0 =A0 =A0 =A0case 3: > + =A0 =A0 =A0 =A0 =A0start_address =3D u_buf[0].unsigned_regval + > 4; > + =A0 =A0 =A0 =A0 =A0arm_insn_r->mem_rec_count =3D > register_count; > + =A0 =A0 =A0 =A0 =A0while (register_count) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 1] =3D start_address; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - > 2] =3D 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0start_address =3D start_address + 4; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0register_count--; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0break; > + > + =A0 =A0 =A0 =A0default: > + =A0 =A0 =A0 =A0 =A0gdb_assert_not_reached ("Invalid addressing > mode for insn"); > + =A0 =A0 =A0 =A0break; > + =A0 =A0 =A0} > + > + =A0 =A0/* Base register also changes; based on condition > and W bit. =A0*/ > + =A0 =A0/* We save it anyway without optimization. =A0*/ > + =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0arm_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + > + =A0REG_ALLOC (arm_insn_r->arm_regs, > arm_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (arm_insn_r->arm_mems, > arm_insn_r->mem_rec_count, record_buf_mem); > + =A0return 0; > +} > + > +/* Handling opcode 101 insns. =A0*/ > + > +static int > +arm_handle_brn_insn (insn_decode_record *arm_insn_r) > +{ > + > + =A0uint32_t record_buf[8]; > + > + =A0/* Handle B, BL, BLX(1) insns. =A0*/ > + =A0/* Wihtout optmization we save link register, > + =A0 =A0 =A0 =A0CSPR for the insn which changes T bit. =A0*/ > + =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0record_buf[1] =3D ARM_LR_REGNUM; > + =A0arm_insn_r->reg_rec_count =3D 2; > + > + =A0REG_ALLOC (arm_insn_r->arm_regs, > arm_insn_r->reg_rec_count, record_buf); > + > + =A0return 0; > +} > + > +/* Handling opcode 110 insns. =A0*/ > + > +static int > +arm_handle_coproc_insn (insn_decode_record *arm_insn_r) > +{ > + =A0printf_unfiltered (_("Process record does not support > instruction " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "0x%0x at address %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 arm_insn_r->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress > (arm_insn_r->gdbarch, arm_insn_r->this_addr)); > + > + =A0 return -1; > +} > + > +/* Handling opcode 111 insns. =A0*/ > + > +static int > +arm_handle_coproc_data_proc_insn (insn_decode_record > *arm_insn_r) > +{ > + =A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep > (arm_insn_r->gdbarch); > + =A0 struct regcache *reg_cache =3D arm_insn_r->regcache; > + > + =A0 uint32_t shift_imm =3D 0; > + =A0 uint32_t reg_src1 =3D 0, reg_src2 =3D 0, addr_mode =3D 0; > + =A0 uint32_t start_address =3D 0; > + > + =A0 /* Handle SWI insn; system call would be handled over > here. =A0*/ > + > + =A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, > 24, 27); > + =A0 if (15 =3D=3D arm_insn_r->opcode) > + =A0 { > + =A0 =A0 =A0 =A0/* Handle arm syscall insn. =A0*/ > + =A0 =A0 =A0 =A0if (tdep->arm_swi_record !=3D NULL) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tdep->arm_swi_record(reg_cache); > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0printf_unfiltered (_("no syscall record > support\n")); > + =A0 =A0 =A0 =A0 =A0 =A0return -1; > + =A0 =A0 =A0 =A0 =A0} > + =A0 } > + > + =A0 printf_unfiltered (_("Process record does not support > instruction " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "0x%0x at address > %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > arm_insn_r->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress > (arm_insn_r->gdbarch, > arm_insn_r->this_addr)); > + =A0 return -1; > +} > + > +/* Handling opcode 000 insns. =A0*/ > + > +static int > +thumb_handle_shift_add_sub_insn (insn_decode_record > *thumb_insn_r) > +{ > + =A0uint32_t record_buf[8]; > + =A0uint32_t reg_src1 =3D 0; > + > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); > + > + =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0record_buf[1] =3D reg_src1; > + =A0thumb_insn_r->reg_rec_count =3D 2; > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + > + =A0return 0; > +} > + > + > +/* Handling opcode 001 insns. =A0*/ > + > +static int > +thumb_handle_add_sub_cmp_mov_insn (insn_decode_record > *thumb_insn_r) > +{ > + =A0uint32_t record_buf[8]; > + =A0uint32_t reg_src1 =3D 0; > + > + =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > + > + =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0record_buf[1] =3D reg_src1; > + =A0thumb_insn_r->reg_rec_count =3D 2; > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + > + =A0return 0; > +} > + > +/* Handling opcode 010 insns. =A0*/ > + > +static int > +thumb_handle_ld_st_reg_offset_insn (insn_decode_record > *thumb_insn_r) > +{ > + =A0struct regcache *reg_cache =3D > =A0thumb_insn_r->regcache; > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0uint32_t reg_src1 =3D 0, reg_src2 =3D 0; > + =A0uint32_t opcode1 =3D 0, opcode2 =3D 0, opcode3 =3D 0; > + > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0 =A0gdb_byte buf[4]; > + =A0 =A0} u_buf[2]; > + > + =A0opcode1 =3D bits (thumb_insn_r->arm_insn, 10, 12); > + > + =A0if (bit (thumb_insn_r->arm_insn, 12)) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle load/store register offset. =A0*/ > + =A0 =A0 =A0opcode2 =3D bits (thumb_insn_r->arm_insn, 9, > 10); > + =A0 =A0 =A0if ((opcode2 >=3D 12) && (opcode2 <=3D > 15)) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH. > =A0*/ > + =A0 =A0 =A0 =A0 =A0reg_src1 =3D bits > (thumb_insn_r->arm_insn,0, 2); > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else if ((opcode2 >=3D 8) && (opcode2 > <=3D 10)) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* STR(2), STRB(2), STRH(2) . =A0*/ > + =A0 =A0 =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, > 3, 5); > + =A0 =A0 =A0 =A0 =A0reg_src2 =3D bits (thumb_insn_r->arm_insn, > 6, 8); > + =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0, > &u_buf[0].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > reg_src2 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0, > &u_buf[1].unsigned_regval); > + =A0 =A0 =A0 =A0 =A0if (8 =3D=3D opcode2) > + =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 4; =A0 =A0/* STR (2). > =A0*/ > + =A0 =A0 =A0 =A0 =A0else if (10 =3D=3D opcode2) > + =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 1; =A0 =A0/* =A0STRB > (2). =A0*/ > + =A0 =A0 =A0 =A0 =A0else if (9 =3D=3D opcode2) > + =A0 =A0 =A0 =A0 =A0 =A0record_buf_mem[0] =3D 2; =A0 =A0/* STRH (2). > =A0*/ > + =A0 =A0 =A0 =A0 =A0record_buf_mem[1] =3D > u_buf[0].unsigned_regval+u_buf[1].unsigned_regval; >=20 > + =A0 =A0 =A0 =A0 =A0thumb_insn_r->mem_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if (bit (thumb_insn_r->arm_insn, 11)) > + =A0 =A0{ > + =A0 =A0 =A0/* Handle load from literal pool. =A0*/ > + =A0 =A0 =A0/* LDR(3). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, > 10); >=20 > + =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if (opcode1) > + =A0 =A0{ > + =A0 =A0 =A0opcode2 =3D bits (thumb_insn_r->arm_insn, 8, > 9); > + =A0 =A0 =A0opcode3 =3D bits (thumb_insn_r->arm_insn, 0, > 2); > + =A0 =A0 =A0if ((3 =3D=3D opcode2) && (!opcode3)) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* Branch with exchange. =A0*/ > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0else > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0/* Format 8; special data processing insns. > =A0*/ > + =A0 =A0 =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, > 0, 2); > + =A0 =A0 =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0 =A0 =A0record_buf[1] =3D reg_src1; > + =A0 =A0 =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0/* Format 5; data processing insns. =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, > 2); > + =A0 =A0 =A0if (bit (thumb_insn_r->arm_insn, 7)) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0reg_src1 =3D reg_src1 + 8; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0record_buf[1] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 2; > + =A0 =A0} > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (thumb_insn_r->arm_mems, > thumb_insn_r->mem_rec_count, > record_buf_mem); > + > + =A0return 0; > +} > + > +/* Handling opcode 001 insns. =A0*/ > + > +static int > +thumb_handle_ld_st_imm_offset_insn (insn_decode_record > *thumb_insn_r) > +{ > + =A0struct regcache *reg_cache =3D > thumb_insn_r->regcache; > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0uint32_t reg_val1 =3D 0; > + =A0uint32_t reg_src1 =3D 0; > + =A0uint32_t opcode =3D 0, immed_5 =3D 0; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); > + > + =A0if (opcode) > + =A0 =A0{ > + =A0 =A0 =A0/* LDR(1). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, > 2); > + =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0/* STR(1). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 3, > 5); > + =A0 =A0 =A0immed_5 =3D bits (thumb_insn_r->arm_insn, 6, > 10); > + =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf.unsigned_regval); > + =A0 =A0 =A0record_buf_mem[0] =3D 4; > + =A0 =A0 =A0record_buf_mem[1] =3D u_buf.unsigned_regval + > (immed_5 * 4); > + =A0 =A0 =A0thumb_insn_r->mem_rec_count =3D 1; > + =A0 =A0} > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (thumb_insn_r->arm_mems, > thumb_insn_r->mem_rec_count, > record_buf_mem); > + > + =A0return 0; > +} > + > +/* Handling opcode 100 insns. =A0*/ > + > +static int > +thumb_handle_ld_st_stack_insn (insn_decode_record > *thumb_insn_r) > +{ > + =A0struct regcache *reg_cache =3D > thumb_insn_r->regcache; > + =A0uint32_t record_buf[8], record_buf_mem[8]; > + > + =A0uint32_t reg_val1 =3D 0; > + =A0uint32_t reg_src1 =3D 0; > + =A0uint32_t opcode =3D 0, immed_8 =3D 0, immed_5 =3D 0; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); > + > + =A0if (3 =3D=3D opcode) > + =A0 =A0{ > + =A0 =A0 =A0/* LDR(4). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, > 10); > + =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if (1 =3D=3D opcode) > + =A0 =A0{ > + =A0 =A0 =A0/* LDRH(1). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, > 2); > + =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if (2 =3D=3D opcode) > + =A0 =A0{ > + =A0 =A0 =A0/* STR(3). =A0*/ > + =A0 =A0 =A0immed_8 =3D bits (thumb_insn_r->arm_insn, 0, > 7); > + =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > ARM_SP_REGNUM > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf.unsigned_regval); > + =A0 =A0 =A0record_buf_mem[0] =3D 4; > + =A0 =A0 =A0record_buf_mem[1] =3D u_buf.unsigned_regval + > (immed_8 * 4); > + =A0 =A0 =A0thumb_insn_r->mem_rec_count =3D 1; > + =A0 =A0} > + =A0else if (0 =3D=3D opcode) > + =A0 =A0{ > + =A0 =A0 =A0/* STRH(1). =A0*/ > + =A0 =A0 =A0immed_5 =3D bits (thumb_insn_r->arm_insn, 6, > 10); > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 3, > 5); > + =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, reg_src1 > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf.unsigned_regval); > + =A0 =A0 =A0record_buf_mem[0] =3D 2; > + =A0 =A0 =A0record_buf_mem[1] =3D u_buf.unsigned_regval + > (immed_5 * 2); > + =A0 =A0 =A0thumb_insn_r->mem_rec_count =3D 1; > + =A0 =A0} > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (thumb_insn_r->arm_mems, > thumb_insn_r->mem_rec_count, > record_buf_mem); > + > + =A0return 0; > +} > + > +/* Handling opcode 101 insns. =A0*/ > + > +static int > +thumb_handle_misc_insn (insn_decode_record *thumb_insn_r) > +{ > + =A0struct regcache *reg_cache =3D > thumb_insn_r->regcache; > + > + =A0uint32_t reg_val1 =3D 0; > + =A0uint32_t reg_src1 =3D 0; > + =A0uint32_t opcode =3D 0, opcode1 =3D 0, opcode2 =3D 0, immed_8 > =3D 0, immed_5 =3D 0; > + =A0uint32_t register_bits =3D 0, register_count =3D 0; > + =A0uint32_t register_list[8] =3D {0}, index =3D 0, > start_address =3D 0; > + =A0uint32_t record_buf[24], record_buf_mem[48]; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); > + =A0opcode1 =3D bits (thumb_insn_r->arm_insn, 8, 12); > + =A0opcode2 =3D bits (thumb_insn_r->arm_insn, 9, 12); > + > + =A0if (14 =3D=3D opcode2) > + =A0 =A0{ > + =A0 =A0 =A0/* POP. =A0*/ > + =A0 =A0 =A0register_bits =3D bits (thumb_insn_r->arm_insn, > 0, 7); > + =A0 =A0 =A0while (register_bits) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0if (register_bits & 0x00000001) > + =A0 =A0 =A0 =A0 =A0 =A0register_list[register_count++] =3D 1; > + =A0 =A0 =A0 =A0 =A0register_bits =3D register_bits >> 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0record_buf[register_count] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0record_buf[register_count + 1] =3D ARM_SP_REGNUM; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D register_count + > 2; > + =A0 =A0 =A0for (register_count =3D 0; register_count < 8; > register_count++) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0if =A0(register_list[register_count]) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf[index] =3D register_count; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0index++; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if (10 =3D=3D opcode2) > + =A0 =A0{ > + =A0 =A0 =A0/* PUSH. =A0*/ > + =A0 =A0 =A0register_bits =3D bits (thumb_insn_r->arm_insn, > 0, 7); > + =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, > ARM_PC_REGNUM > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf.unsigned_regval); > + =A0 =A0 =A0while (register_bits) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0if (register_bits & 0x00000001) > + =A0 =A0 =A0 =A0 =A0 =A0 register_count++; > + =A0 =A0 =A0 =A0 =A0register_bits =3D register_bits >> 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0start_address =3D u_buf.unsigned_regval - =A0\ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (4 * (bit > (thumb_insn_r->arm_insn, 8) + register_count)) ; > + =A0 =A0 =A0thumb_insn_r->mem_rec_count =3D register_count; > + =A0 =A0 =A0while (register_count) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - 1] =3D > start_address; > + =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - 2] =3D > 4; > + =A0 =A0 =A0 =A0 =A0start_address =3D start_address + 4; > + =A0 =A0 =A0 =A0 =A0register_count--; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0record_buf[0] =3D ARM_SP_REGNUM; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if (0x1E =3D=3D opcode1) > + =A0 =A0{ > + =A0 =A0 =A0/* BKPT insn. =A0*/ > + =A0 =A0 =A0/* Handle enhanced software breakpoint insn, > BKPT. =A0*/ > + =A0 =A0 =A0/* CPSR is changed to be executed in ARM state, > =A0disabling normal > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 interrupts, entering abort mode. > =A0*/ > + =A0 =A0 =A0/* Accorindly to high vector configuration PC is > set accordingly. =A0*/ > + =A0 =A0 =A0/* FIX ME ? =A0what if user hit breakpoint and > type reverse, in > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 that case, we need to go back with > previous CPSR and > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 Program Counter.. =A0*/ > + =A0 =A0 =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0 =A0 =A0record_buf[1] =3D ARM_LR_REGNUM; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 2; > + =A0 =A0 =A0/* Save SPSR also; how?. =A0*/ > + =A0 =A0 =A0printf_unfiltered (_("Process record does not > support instruction " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "0x%0x at address > %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0thumb_insn_r->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress > (thumb_insn_r->gdbarch, > thumb_insn_r->this_addr)); > + =A0 =A0 =A0return -1; > + =A0 =A0} > + =A0else if ((0 =3D=3D opcode) || (1 =3D=3D opcode)) > + =A0 =A0{ > + =A0 =A0 =A0 /* ADD(5), ADD(6). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, > 10); > + =A0 =A0 =A0record_buf[0] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + =A0else if (2 =3D=3D opcode) > + =A0 =A0{ > + =A0 =A0 =A0/* ADD(7), SUB(4). =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, > 10); > + =A0 =A0 =A0record_buf[0] =3D ARM_SP_REGNUM; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D 1; > + =A0 =A0} > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (thumb_insn_r->arm_mems, > thumb_insn_r->mem_rec_count, > record_buf_mem); > + > + =A0return 0; > +} > + > +/* Handling opcode 110 insns. =A0*/ > + > +static int > +thumb_handle_swi_insn (insn_decode_record *thumb_insn_r) > +{ > + =A0struct gdbarch_tdep *tdep =3D gdbarch_tdep > (thumb_insn_r->gdbarch); > + =A0struct regcache *reg_cache =3D > thumb_insn_r->regcache; > + > + =A0uint32_t reg_val1 =3D 0; > + =A0uint32_t reg_src1 =3D 0; > + =A0uint32_t opcode1 =3D 0, opcode2 =3D 0, register_bits =3D 0, > register_count =3D 0; > + =A0uint32_t register_list[8] =3D {0}, index =3D 0, > start_address =3D 0; > + =A0uint32_t record_buf[24], record_buf_mem[48]; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0opcode1 =3D bits (thumb_insn_r->arm_insn, 8, 12); > + =A0opcode2 =3D bits (thumb_insn_r->arm_insn, 11, 12); > + > + =A0if (1 =3D=3D opcode2) > + =A0 =A0{ > + > + =A0 =A0 =A0/* LDMIA. =A0*/ > + =A0 =A0 =A0register_bits =3D bits (thumb_insn_r->arm_insn, > 0, 7); > + =A0 =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, > 10); > + =A0 =A0 =A0while (register_bits) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0if (register_bits & 0x00000001) > + =A0 =A0 =A0 =A0 =A0 =A0register_list[register_count++] =3D 1; > + =A0 =A0 =A0 =A0 =A0register_bits =3D register_bits >> 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0record_buf[register_count] =3D reg_src1; > + =A0 =A0 =A0thumb_insn_r->reg_rec_count =3D register_count + > 1; > + =A0 =A0 =A0for (register_count =3D 0; register_count < 8; > register_count++) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0if =A0(register_list[register_count]) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0record_buf[index] =3D register_count; > + =A0 =A0 =A0 =A0 =A0 =A0 =A0index++; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if (0 =3D=3D opcode2) > + =A0 =A0{ > + =A0 =A0 =A0/* It handles both STMIA. =A0*/ > + =A0 =A0 =A0register_bits =3D bits (thumb_insn_r->arm_insn, > 0, 7); > + =A0 =A0 =A0/* Get Rn. =A0*/ > + =A0 =A0 =A0reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, > 10); > + =A0 =A0 =A0regcache_raw_read_unsigned (reg_cache, reg_src1, > &u_buf.unsigned_regval); > + =A0 =A0 =A0while (register_bits) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0if (register_bits & 0x00000001) > + =A0 =A0 =A0 =A0 =A0 =A0 register_count++; > + =A0 =A0 =A0 =A0 =A0register_bits =3D register_bits >> 1; > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0start_address =3D u_buf.unsigned_regval; > + =A0 =A0 =A0thumb_insn_r->mem_rec_count =3D register_count; > + =A0 =A0 =A0while (register_count) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - 1] =3D > start_address; > + =A0 =A0 =A0 =A0 =A0record_buf_mem[(register_count * 2) - 2] =3D > 4; > + =A0 =A0 =A0 =A0 =A0start_address =3D start_address + 4; > + =A0 =A0 =A0 =A0 =A0register_count--; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if (0x1F =3D=3D opcode1) > + =A0 =A0 { > + =A0 =A0 =A0 =A0/* Handle arm syscall insn. =A0*/ > + =A0 =A0 =A0 =A0if (tdep->arm_swi_record !=3D NULL) > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0tdep->arm_swi_record(reg_cache); > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0else > + =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0printf_unfiltered (_("no syscall record > support\n")); > + =A0 =A0 =A0 =A0 =A0 =A0return -1; > + =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 } > + > + =A0/* B(1), conditional branch is automatically taken care > in process_record, > + =A0 =A0 =A0 =A0as PC is saved there. =A0*/ > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + =A0MEM_ALLOC (thumb_insn_r->arm_mems, > thumb_insn_r->mem_rec_count, > record_buf_mem); > + > + =A0return 0; > +} > + > +/* Handling opcode 111 insns. =A0*/ > + > +static int > +thumb_handle_branch_insn (insn_decode_record > *thumb_insn_r) > +{ > + =A0uint32_t record_buf[8]; > + =A0uint32_t reg_val1 =3D 0; > + =A0uint32_t reg_src1 =3D 0; > + =A0uint32_t opcode =3D 0, immed_5 =3D 0; > + > + > + =A0/* BL , BLX(1). =A0*/ > + =A0record_buf[0] =3D ARM_PS_REGNUM; > + =A0record_buf[1] =3D ARM_LR_REGNUM; > + =A0thumb_insn_r->reg_rec_count =3D 2; > + > + =A0/* B(2) is automatically taken care in process_record, > as PC is saved > + =A0 =A0 =A0 =A0there. =A0*/ > + > + =A0REG_ALLOC (thumb_insn_r->arm_regs, > thumb_insn_r->reg_rec_count, record_buf); > + > + =A0return 0; > +} > + > + > +/* Decode arm/thumb insn depending on condition cods and > opcodes; and dispatch > it. =A0*/ > + > +static int > +decode_insn (insn_decode_record *arm_record, uint32_t > insn_size) > +{ > + > + =A0/* (Starting from numerical 0); bits 25, 26, 27 decodes > type of arm > instruction. =A0*/ > + =A0static int (*const arm_handle_insn[8]) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0(insn_decode_record*) =3D > + =A0{ > + =A0 =A0 =A0arm_handle_data_proc_misc_ld_str_insn, =A0 =A0/* > 000. =A0*/ > + =A0 =A0 =A0arm_handle_data_proc_imm_insn, =A0 =A0 =A0 =A0 =A0 > =A0/* 001. =A0*/ > + =A0 =A0 =A0arm_handle_ld_st_imm_offset_insn, =A0 =A0 =A0 =A0 /* > 010. =A0*/ > + =A0 =A0 =A0arm_handle_ld_st_reg_offset_insn, =A0 =A0 =A0 =A0 /* > 011. =A0*/ > + =A0 =A0 =A0arm_handle_ld_st_multiple_insn, =A0 =A0 =A0 =A0 =A0 /* > 100. =A0*/ > + =A0 =A0 =A0arm_handle_brn_insn, =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0 =A0/* 101. =A0*/ > + =A0 =A0 =A0arm_handle_coproc_insn, =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0 /* 110. =A0*/ > + =A0 =A0 =A0arm_handle_coproc_data_proc_insn =A0 =A0 =A0 =A0 =A0/* > 111. =A0*/ > + =A0}; > + > + =A0/* (Starting from numerical 0); bits 13,14,15 decodes > type of thumb > instruction. =A0*/ > + =A0static int (*const thumb_handle_insn[8]) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0 =A0(insn_decode_record*) =3D > + =A0{ \ > + =A0 =A0 =A0thumb_handle_shift_add_sub_insn, =A0 =A0 =A0 =A0 /* > 000. =A0*/ > + =A0 =A0 =A0thumb_handle_add_sub_cmp_mov_insn, =A0 =A0 =A0 /* > 001. =A0*/ > + =A0 =A0 =A0thumb_handle_ld_st_reg_offset_insn, =A0 =A0 =A0/* > 010. =A0*/ > + =A0 =A0 =A0thumb_handle_ld_st_imm_offset_insn, =A0 =A0 =A0/* > 011. =A0*/ > + =A0 =A0 =A0thumb_handle_ld_st_stack_insn, =A0 =A0 =A0 =A0 =A0 /* > 100. =A0*/ > + =A0 =A0 =A0thumb_handle_misc_insn, =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0/* 101. =A0*/ > + =A0 =A0 =A0thumb_handle_swi_insn, =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > /* 110. =A0*/ > + =A0 =A0 =A0thumb_handle_branch_insn =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > /* 111. =A0*/ > + =A0}; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0gdb_byte buf[insn_size]; > + =A0 =A0} u_buf; > + > + =A0uint32_t ret=3D0, insn_id =3D 0; > + > + =A0memset (&u_buf, 0, sizeof(u_buf)); > + =A0if (target_read_memory (arm_record->this_addr, > &u_buf.buf[0], insn_size)) > + =A0 =A0{ > + =A0 =A0 =A0if (record_debug) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0printf_unfiltered (_("Process record: error > reading memory at " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "addr %s len > =3D %d.\n"), > + =A0 =A0 =A0 =A0 =A0paddress (arm_record->gdbarch, > arm_record->this_addr), insn_size); > + =A0 =A0 =A0 =A0 =A0return -1; > + =A0 =A0 =A0 =A0} > + =A0 =A0} > + =A0else if (ARM_INSN_SIZE_BYTES =3D=3D insn_size) > + =A0 =A0{ > + =A0 =A0 =A0arm_record->arm_insn =3D (uint32_t) > extract_unsigned_integer (&u_buf.buf[0] > + =A0 =A0 =A0 =A0 =A0 =A0 , ARM_INSN_SIZE_BYTES , > gdbarch_byte_order (arm_record->gdbarch)); >=20 > + =A0 =A0 =A0arm_record->cond =3D bits > (arm_record->arm_insn, 28, 31); > + =A0 =A0 =A0insn_id =3D bits (arm_record->arm_insn, 25, > 27); > + =A0 =A0 =A0ret =3D (0x0F !=3D arm_record->cond) > + =A0 =A0 =A0 =A0 =A0 =A0? arm_handle_insn[insn_id] (arm_record) > + =A0 =A0 =A0 =A0 =A0 =A0: handle_extension_space (arm_record); > + =A0 =A0} > + =A0else if (THUMB_INSN_SIZE_BYTES =3D=3D insn_size) > + =A0 =A0{ > + =A0 =A0 =A0/* As thumb does not have condition codes, > following field is useless. > */ > + =A0 =A0 =A0arm_record->cond =3D -1; > + =A0 =A0 =A0arm_record->arm_insn =3D (uint32_t) > extract_unsigned_integer (&u_buf.buf[0] > + =A0 =A0 =A0 =A0 =A0 , THUMB_INSN_SIZE_BYTES , > gdbarch_byte_order (arm_record->gdbarch)); > + > + =A0 =A0 =A0insn_id =3D bits (arm_record->arm_insn, 13, > 15); > + =A0 =A0 =A0ret =3D thumb_handle_insn[insn_id] (arm_record); > + =A0 =A0} > + =A0else if (THUMB2_INSN_SIZE_BYTES =3D=3D insn_size) > + =A0 =A0{ > + =A0 =A0 =A0/* Yet to be implemented; handle thumb2 part > here. =A0*/ > + =A0 =A0 =A0printf_unfiltered (_("Process record does not > support instruction 0x%0x " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "at address %s.\n"), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > arm_record->arm_insn, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 paddress > (arm_record->gdbarch, > arm_record->this_addr)); > + =A0 =A0 =A0ret =3D -1; > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0/* Throw assertion. =A0*/ > + =A0 =A0 =A0gdb_assert(0); > + =A0 =A0} > + > + =A0return ret; > +} > + > +/* Parse the current instruction and record the values of > the registers and > + =A0 memory that will be changed in current instruction to > "record_arch_list". > + =A0 Return -1 if something is wrong.. =A0*/ > + > +int > +arm_process_record (struct gdbarch *gdbarch, struct > regcache *regcache, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CORE_ADDR > insn_addr) > +{ > + > + =A0enum bfd_endian byte_order =3D gdbarch_byte_order > (gdbarch); > + =A0uint32_t no_of_rec =3D 0; > + =A0uint32_t ret =3D 0; > + =A0ULONGEST t_bit =3D 0; > + > + =A0struct > + =A0 =A0{ > + =A0 =A0 =A0ULONGEST unsigned_regval; > + =A0 =A0} u_buf; > + > + =A0insn_decode_record arm_record; > + =A0memset (&u_buf, 0, sizeof(u_buf)); > + > + =A0memset (&arm_record, 0, sizeof > (insn_decode_record)); > + =A0arm_record.regcache =3D regcache; > + =A0arm_record.this_addr =3D insn_addr; > + =A0arm_record.gdbarch =3D gdbarch; > + > + > + =A0if (record_debug > 1) > + =A0 =A0{ > + =A0 =A0 =A0fprintf_unfiltered (gdb_stdlog, "Process record: > arm_process_record " > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0"addr =3D %s\n", > + =A0 =A0 =A0paddress (gdbarch, arm_record.this_addr)); > + =A0 =A0} > + > + =A0/* Check the insn, whether it is thumb or arm one. > =A0*/ > + > + =A0t_bit =3D arm_psr_thumb_bit (arm_record.gdbarch); > + =A0regcache_raw_read_unsigned (arm_record.regcache, > ARM_PS_REGNUM > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0, > &u_buf.unsigned_regval); > + > + =A0if (!(u_buf.unsigned_regval & t_bit)) > + =A0 =A0{ > + =A0 =A0 =A0/* We are decoding arm insn. =A0*/ > + =A0 =A0 =A0ret =3D decode_insn (&arm_record, > ARM_INSN_SIZE_BYTES); > + =A0 =A0} > + =A0else > + =A0 =A0{ > + =A0 =A0 =A0/* We are decoding thumb insn. =A0*/ > + =A0 =A0 =A0ret =3D decode_insn (&arm_record, > THUMB_INSN_SIZE_BYTES); > + =A0 =A0} > + > + =A0if (0 =3D=3D ret) > + =A0 =A0{ > + =A0 =A0 =A0/* Record registers. =A0*/ > + =A0 =A0 =A0record_arch_list_add_reg (arm_record.regcache, > ARM_PC_REGNUM); > + =A0 =A0 =A0if (arm_record.arm_regs) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0for (no_of_rec =3D 0; no_of_rec < > arm_record.reg_rec_count; > no_of_rec++) > + =A0 =A0 =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0if (record_arch_list_add_reg > (arm_record.regcache \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 > =A0 =A0 , (arm_record.arm_regs[no_of_rec]))) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0 =A0 =A0 =A0} > + =A0 =A0 =A0 =A0} > + =A0 =A0 =A0/* Record memories. =A0*/ > + =A0 =A0 =A0if (arm_record.arm_mems) > + =A0 =A0 =A0 =A0{ > + =A0 =A0 =A0 =A0 =A0for (no_of_rec =3D 0; no_of_rec < > arm_record.mem_rec_count; > no_of_rec++) > + =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 =A0if (record_arch_list_add_mem \ > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0((CORE_ADDR)arm_record.arm_mems[no_of_rec].addr, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 > =A0arm_record.arm_mems[no_of_rec].len)) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0ret =3D -1; > + =A0 =A0 =A0 =A0 =A0 } > + =A0 =A0 =A0 =A0} > + > + =A0 =A0 =A0if (record_arch_list_add_end ()) > + =A0 =A0 =A0 =A0ret =3D -1; > + =A0 =A0} > + > + =A0if (arm_record.arm_regs) > + =A0 =A0xfree (arm_record.arm_regs); > + =A0if (arm_record.arm_mems) > + =A0 =A0xfree (arm_record.arm_mems); > + > + =A0return ret; > +} > diff -urN arm_orig/arm-tdep.h arm_new/arm-tdep.h > --- arm_orig/arm-tdep.h =A0 =A02011-03-03 09:21:13.000000000 > +0530 > +++ arm_new/arm-tdep.h =A0 =A02011-05-07 14:20:31.000000000 > +0530 > @@ -200,6 +200,9 @@ > =A0 /* Return the expected next PC if FRAME is stopped at a > syscall > =A0 =A0 =A0instruction. =A0*/ > =A0 CORE_ADDR (*syscall_next_pc) (struct frame_info > *frame); > + > + =A0 /* Parse swi insn args, sycall record. =A0*/ > + =A0int (*arm_swi_record) (struct regcache *regcache); > =A0}; >=20 > =A0/* Structures used for displaced stepping. =A0*/ > @@ -310,6 +313,10 @@ > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct > displaced_step_closure *, > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CORE_ADDR, CORE_ADDR, > struct regcache *); >=20 > +extern int arm_process_record (struct gdbarch *gdbarch, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct > regcache *regcache, CORE_ADDR addr); > + > + > =A0/* Functions exported from armbsd-tdep.h. =A0*/ >=20 > =A0/* Return the appropriate register set for the core > section identified >