From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14844 invoked by alias); 22 Sep 2011 14:08:53 -0000 Received: (qmail 14823 invoked by uid 22791); 22 Sep 2011 14:08:44 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_EG,TW_NR,TW_SB X-Spam-Check-By: sourceware.org Received: from mail-wy0-f169.google.com (HELO mail-wy0-f169.google.com) (74.125.82.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 22 Sep 2011 14:08:17 +0000 Received: by wyf22 with SMTP id 22so2832524wyf.0 for ; Thu, 22 Sep 2011 07:08:15 -0700 (PDT) MIME-Version: 1.0 Received: by 10.216.179.205 with SMTP id h55mr3699936wem.51.1316700494920; Thu, 22 Sep 2011 07:08:14 -0700 (PDT) Received: by 10.180.94.234 with HTTP; Thu, 22 Sep 2011 07:08:14 -0700 (PDT) In-Reply-To: <1316404058.27177.YahooMailNeo@web112502.mail.gq1.yahoo.com> References: <998639.46560.qm@web112516.mail.gq1.yahoo.com> <321260.58442.qm@web112504.mail.gq1.yahoo.com> <1316327455.23344.YahooMailNeo@web112509.mail.gq1.yahoo.com> <1316404058.27177.YahooMailNeo@web112502.mail.gq1.yahoo.com> Date: Thu, 22 Sep 2011 17:12:00 -0000 Message-ID: Subject: Re: [PATCH] arm reversible : From: oza Pawandeep To: Tom Tromey , "gdb-patches@sourceware.org" , =?ISO-8859-1?Q?Petr_Hluz=EDn?= , chandra krishnappa 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-09/txt/msg00410.txt.bz2 Hello Chandra, Let me know if you are planning to do anymore basic testing on this patch. @Tom: is it possible to get this patch move in, of course I have been keen on any review comment; but it has been lying around for a long time. and I would like to move to phase-3 implementation then. Regards, Oza. On Mon, Sep 19, 2011 at 9:17 AM, paawan oza wrote: > > > Hi all, > > Sorry for delay in fixing review comments. > > Thanks Chandra for doing testing and working on porintg x86 tcl test case= s to arm reversible. > please find the latest version of the patch after fixing couple of bugs a= nd review comment fix from Tom. > > PATCH STARTS > ---------------------------------- > diff -urN arm_orig/arm-linux-tdep.c arm_new/arm-linux-tdep.c > --- arm_orig/arm-linux-tdep.c=A0=A0=A0 2011-07-28 09:40:19.000000000 +0530 > +++ arm_new/arm-linux-tdep.c=A0=A0=A0 2011-07-28 09:41:06.000000000 +0530 > @@ -1025,6 +1025,9 @@ > =A0=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=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 svr4_fetch_= objfile_link_map); > > +=A0 /* Enable process record.=A0 */ > +=A0 set_gdbarch_process_record (gdbarch, arm_process_record); > + > =A0=A0 tramp_frame_prepend_unwinder (gdbarch, > =A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0=A0 &arm_linux_sigreturn_tramp_fra= me); > =A0=A0 tramp_frame_prepend_unwinder (gdbarch, > @@ -1054,6 +1057,8 @@ > > > =A0=A0 tdep->syscall_next_pc =3D arm_linux_syscall_next_pc; > + > +=A0 tdep->arm_swi_record =3D NULL; > =A0} > > =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=A0=A0 2011-07-28 09:40:19.000000000 +0530 > +++ arm_new/arm-tdep.c=A0=A0=A0 2011-09-18 12:55:12.000000000 +0530 > @@ -55,6 +55,8 @@ > =A0#include "gdb_assert.h" > =A0#include "vec.h" > > +#include "record.h" > + > =A0#include "features/arm-with-m.c" > > =A0static int arm_debug; > @@ -8821,3 +8823,1769 @@ > =A0=A0=A0=A0 =A0=A0=A0 =A0=A0=A0 =A0=A0 NULL, /* FIXME: i18n: "ARM debugg= ing is %s.=A0 */ > =A0=A0=A0=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=A0=A0 unsigned int reg_len =3D LENGTH; \ > +=A0=A0=A0 if (reg_len) \ > +=A0=A0=A0=A0=A0 { \ > +=A0=A0=A0=A0=A0=A0=A0 REGS =3D XNEWVEC (uint32_t, reg_len); \ > +=A0=A0=A0=A0=A0=A0=A0 memcpy(®S[0],&RECORD_BUF[0],sizeof(uint32_t)*LE= NGTH); \ > +=A0=A0=A0=A0=A0 } \ > +=A0 } \ > +while (0) > + > +#define MEM_ALLOC(MEMS,LENGTH,RECORD_BUF) \ > +do=A0 \ > +=A0 { \ > +=A0=A0=A0 unsigned int mem_len =3D LENGTH; \ > +=A0=A0=A0 if (mem_len) \ > +=A0=A0=A0=A0=A0 { \ > +=A0=A0=A0=A0=A0=A0=A0 MEMS =3D=A0 XNEWVEC (struct arm_mem_r, mem_len);= =A0 \ > +=A0=A0=A0=A0=A0=A0=A0 memcpy(&MEMS->len,&RECORD_BUF[0],sizeof(struct arm= _mem_r) * LENGTH); \ > +=A0=A0=A0=A0=A0 } \ > +=A0 } > \ > +while (0) > + > + > +/* ARM memory record structure.=A0 */ > +struct arm_mem_r > +{ > +=A0 uint32_t len;=A0=A0=A0=A0 /* Record length.=A0 */ > +=A0 CORE_ADDR addr;=A0=A0 /* Memory address.=A0 */ > +}; > + > +/* ARM instruction record contains opcode of current insn and execution = state (before entry to > +decode_insn() ), contains list of to-be-modified registers and memory bl= ocks (on return from > +decode_insn() ).=A0 */ > +typedef struct insn_decode_record_t > +{ > +=A0 struct gdbarch *gdbarch; > +=A0 struct regcache *regcache; > +=A0 CORE_ADDR this_addr;=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Address of the in= sn being decoded.=A0 */ > +=A0 uint32_t arm_insn;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Should accomm= odate thumb.=A0 */ > +=A0 uint32_t > cond;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Condition code.=A0 = */ > +=A0 uint32_t opcode;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Insn opco= de.=A0 */ > +=A0 uint32_t decode;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Insn deco= de bits.=A0 */ > +=A0 uint32_t mem_rec_count;=A0=A0=A0=A0=A0=A0 /* No of mem records */ > +=A0 uint32_t reg_rec_count;=A0=A0=A0=A0=A0=A0 /* No of reg records */ > +=A0 uint32_t *arm_regs;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Registers to be= saved for this record.=A0 */ > +=A0 struct arm_mem_r *arm_mems;=A0=A0 /* Memory to be saved for this rec= ord.=A0 */ > +} insn_decode_record; > + > + > +/* Checks ARM SBZ and SBO mandatory fields.=A0 */ > + > +static int > +sbo_sbz (uint32_t insn, > uint32_t bit_num, uint32_t len, uint32_t sbo) > +{ > +=A0 uint32_t ones =3D bits (insn, bit_num - 1, (bit_num -1) + (len - 1)); > + > +=A0 if (!len) > +=A0=A0=A0 return 1; > + > +=A0 if (!sbo) > +=A0=A0=A0 ones =3D ~ones; > + > +=A0 while (ones) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 if (!(ones & sbo)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 return 0; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 ones =3D ones >> 1; > +=A0=A0=A0 } > +=A0 return 1; > +} > + > +/* Handling ARM extension space insns.=A0 */ > + > +static int > +handle_extension_space (insn_decode_record *arm_insn_r) > +{ > +=A0 uint32_t ret =3D 0; > +=A0 uint32_t opcode1 =3D 0, opcode2 =3D 0; > + > +=A0 opcode1 =3D bits > (arm_insn_r->arm_insn, 25, 27); > +=A0 if (3 =3D=3D opcode1 && bit (arm_insn_r->arm_insn, 4)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0 /* Undefined instruction on ARM V5; need to handle if la= ter versions > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 define it.=A0 */ > +=A0=A0=A0 } > + > +=A0 opcode2 =3D bits (arm_insn_r->arm_insn, 4, 7); > + > +=A0 if (!opcode1 && (9 =3D=3D opcode2)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0 /* Handle arithmetic insn extension space.=A0 */ > +=A0=A0=A0 } > + > +=A0 opcode1 =3D bits (arm_insn_r->arm_insn, 26, 27); > +=A0 opcode2 =3D bits (arm_insn_r->arm_insn, 23, 24); > + > +=A0 if (!opcode1 && (2 =3D=3D opcode2) && !bit (arm_insn_r->arm_insn, 20= )) > + > { > +=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0 /* Handle control insn extension space.=A0 */ > +=A0=A0=A0 } > + > +=A0 opcode1 =3D bits (arm_insn_r->arm_insn, 25, 27); > +=A0 if (!opcode1 && bit (arm_insn_r->arm_insn, 7) \ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && bit (arm_insn_r->arm= _insn, 4)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0 /* Handle load/store insn extension space.=A0 */ > +=A0=A0=A0 } > + > +=A0 opcode1 =3D bits (arm_insn_r->arm_insn, 23, 27); > +=A0 if ((24 =3D=3D opcode1) && bit (arm_insn_r->arm_insn, 21)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0 /* Handle coprocessor insn extension space.=A0 */ > +=A0=A0=A0 } > + > +=A0 /* To > be done for ARMv5 and later; as of now we return -1.=A0 */ > +=A0 if (-1 =3D=3D ret) > +=A0=A0=A0 printf_unfiltered (_("Process record does not support instruct= ion 0x%0x " > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "at a= ddress %s.\n"), > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_i= nsn_r->arm_insn, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 paddr= ess (arm_insn_r->gdbarch, arm_insn_r->this_addr)); > +=A0 return ret; > +} > + > +/* Handling opcode 000 insns.=A0 */ > + > +static int > +arm_handle_data_proc_misc_ld_str_insn (insn_decode_record *arm_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D arm_insn_r->regcache; > +=A0 uint32_t > record_buf[8], record_buf_mem[8]; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf[2]; > + > + > +=A0 uint32_t reg_src1 =3D 0, reg_src2 =3D 0, reg_dest =3D 0; > +=A0 uint32_t immed_high =3D 0, immed_low =3D 0,offset_8 =3D 0, tgt_mem_a= ddr =3D 0; > +=A0 uint32_t opcode1 =3D 0; > + > +=A0 memset (&u_buf, 0, sizeof (u_buf)); > + > +=A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); > +=A0 arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); > +=A0 opcode1 =3D bits (arm_insn_r->arm_insn, 20, 24); > + > +=A0 /* Data processing insn /multiply insn.=A0 */ > +=A0 if ((9 =3D=3D arm_insn_r->decode) > +=A0=A0=A0=A0 && (((4 <=3D arm_insn_r->opcode) && (7 >=3D arm_insn_r->opc= ode)) > +=A0=A0=A0=A0 ||=A0 ((0 =3D=3D arm_insn_r->opcode) || (1 =3D=3D > arm_insn_r->opcode)))) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle multiply instructions.=A0 */ > +=A0=A0=A0=A0=A0 /* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if ((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=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Handle MLA and MUL.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->ar= m_insn, 16, 19); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > + > } > +=A0=A0=A0=A0=A0=A0=A0 else if ((4 <=3D arm_insn_r->opcode) && (7 >=3D ar= m_insn_r->opcode)) > +=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Handle SMLAL, SMULL, UMLAL, UMULL.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_i= nsn, 16, 19); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D bits (arm_insn_r->arm_i= nsn, 12, 15); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[2] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 3; > +=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 } > +=A0 else if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM) > +=A0=A0=A0=A0=A0=A0=A0 && ((11 =3D=3D arm_insn_r->decode) || (13 =3D=3D a= rm_insn_r->decode))) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* Handle misc load insns, as 20th bit=A0 (L =3D 1= ).=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 /* LDR insn has a capability to do branching, if > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 MOV LR, PC is precce= dded by LDR insn having Rn as R15 > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 in that case, it emu= lates branch and link insn, and hence we > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 need to save CSPR an= d PC as well. I am not sure this is right > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 place as opcode =3D = 010 LDR insn make this happen, if R15 was > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 used.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 reg_dest =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0=A0=A0 if (15 !=3D reg_dest) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->ar= m_insn, 12, 15); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 else > + > { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D reg_dest; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 } > +=A0 else if (((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_insn_r->op= code)) > +=A0=A0=A0=A0=A0 && sbo_sbz (arm_insn_r->arm_insn, 5, 12, 0) > +=A0=A0=A0=A0=A0 && sbo_sbz (arm_insn_r->arm_insn, 13, 4, 1) > +=A0=A0=A0=A0=A0 && 2 =3D=3D bits (arm_insn_r->arm_insn, 20, 21)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle MSR insn.=A0 */ > +=A0=A0=A0=A0=A0 if (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=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* SPSR is going to be changed. */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* How to read SPSR value ?=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf_unfiltered (_("Process record does no= t support instruction " > +=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 "0x%0x at address > %s.\n"), > +=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 arm_insn_r->arm_insn, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if ((9 =3D=3D arm_insn_r->decode) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && ((8 =3D=3D arm_insn_r->opcode) || (10 = =3D=3D arm_insn_r->opcode)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && !bit (arm_insn_r->arm_insn,=A0 INSN_S_= L_BIT_NUM)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* > Handling SWP, SWPB.=A0 */ > +=A0=A0=A0=A0=A0 /* These insns, changes register and memory as well.=A0 = */ > +=A0=A0=A0=A0=A0 /* SWP or SWPB insn.=A0 */ > +=A0=A0=A0=A0=A0 /* Get memory address given by Rn.=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0=A0=A0 regcache_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=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 , &u_buf[0].unsigned_regval); > +=A0=A0=A0=A0=A0 /* SWP insn ?, swaps word.=A0 */ > +=A0=A0=A0=A0=A0 if (8 =3D=3D arm_insn_r->opcode) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D > 4; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* SWPB insn, swaps only byte.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 record_buf_mem[1] =3D u_buf[0].unsigned_regval; > +=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if ((3 =3D=3D arm_insn_r->decode) && (0x12 =3D=3D opcode1) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && sbo_sbz (arm_insn_r->arm_insn, 9, 12, > 1)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle BLX, branch and link/exchange.=A0 */ > +=A0=A0=A0=A0=A0 if (9 =3D=3D arm_insn_r->opcode) > +=A0=A0=A0=A0=A0 { > +=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 and R14 sto= res the return address.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_LR_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if ((7 =3D=3D arm_insn_r->decode) && (0x12 =3D=3D opcode1)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle enhanced software > breakpoint insn, BKPT */ > +=A0=A0=A0=A0=A0 /* CPSR is changed to be executed in ARM state,=A0 disab= ling normal > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 interrupts, entering abort mo= de.=A0 */ > +=A0=A0=A0=A0=A0 /* Accorindly to high vector configuration PC is set acc= ordingly */ > +=A0=A0=A0=A0=A0 /* What if user hit breakpoint and type reverse, in > +=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0=A0=A0 Program Counter.=A0 */ > +=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_LR_REGNUM; > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > + > +=A0=A0=A0=A0=A0 /* Save SPSR also; how?=A0 */ > +=A0=A0=A0=A0=A0 printf_unfiltered (_("Process record does not support in= struction " > +=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 "0x%0x at address %s.\n"), > +=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 arm_insn_r->arm_insn, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 pa= ddress (arm_insn_r->gdbarch, arm_insn_r->this_addr)); > +=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0 } > +=A0 else if ((11 =3D=3D arm_insn_r->decode) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 && !bit > (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > +=A0 { > +=A0=A0=A0 /* Handle enhanced store insns and DSP insns (e.g. LDRD) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 let us begin according to addressing mode= s for store insns > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 STRH insn, addresing modes are taken foll= owing.=A0 */ > +=A0=A0=A0 if ((14 =3D=3D arm_insn_r->opcode) || (10 =3D=3D arm_insn_r->o= pcode)) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* 1) Handle misc store, immediate offset.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 immed_low =3D bits (arm_insn_r->arm_insn, 0, 3); > +=A0=A0=A0=A0=A0=A0=A0 immed_high =3D bits (arm_insn_r->arm_insn, 8, 11); > +=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > + > regcache_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=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=A0=A0 if (15 =3D=3D reg_src1) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* If R15 was used as Rn, hence curren= t PC+8.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 u_buf[0].unsigned_regval =3D u_buf[0].= unsigned_regval + 8; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 offset_8 =3D (immed_high << 4) | > immed_low; > +=A0=A0=A0=A0=A0=A0=A0 /* Calculate target store address.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if (14 =3D=3D arm_insn_r->opcode) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsigned_reg= val + offset_8; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsigned_reg= val - offset_8; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D > 1; > +=A0=A0=A0=A0=A0 } > +=A0=A0=A0 else if ((12 =3D=3D arm_insn_r->opcode) || (8 =3D=3D arm_insn_= r->opcode)) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* 2) Store, register offset.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 /* Get Rm.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 0, 3); > +=A0=A0=A0=A0=A0=A0=A0 /* Get Rn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 reg_src2 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0=A0=A0=A0=A0 regcache_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=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=A0=A0 regcache_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=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 if (15 =3D=3D reg_src2) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* If R15 was used as Rn, hence curren= t PC+8.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 u_buf[0].unsigned_regval =3D u_buf[0].= unsigned_regval + 8; > + > } > +=A0=A0=A0=A0=A0=A0=A0 /* Calculate target store address, Rn +/- Rm, regi= ster offset.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if (12 =3D=3D arm_insn_r->opcode) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsigned_reg= val + u_buf[1].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[1].unsigned_reg= val - u_buf[0].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > + > record_buf_mem[0] =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0=A0=A0 } > +=A0=A0=A0 else if ((11 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_insn= _r->opcode) > +=A0=A0=A0=A0=A0 || (2 =3D=3D arm_insn_r->opcode) || (6 =3D=3D arm_insn_r= ->opcode)) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* 3) Store, immediate pre-indexed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 /* 5) Store, immediate post-indexed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 immed_low =3D bits (arm_insn_r->arm_insn, 0, 3); > +=A0=A0=A0=A0=A0=A0=A0 immed_high =3D bits (arm_insn_r->arm_insn, 8, 11); > +=A0=A0=A0=A0=A0=A0=A0 offset_8 =3D > (immed_high << 4) | immed_low; > +=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0=A0=A0=A0=A0 regcache_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=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 , &u_buf[0].unsigned_regval); > +=A0=A0=A0=A0=A0=A0=A0 /* Calculate target store address, Rn +/- Rm, regi= ster offset.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if ((15 =3D=3D arm_insn_r->opcode) || (6 =3D=3D ar= m_insn_r->opcode)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsigned_reg= val + offset_8; > + > } > +=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsigned_reg= val - offset_8; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 /* Record Rn also as it changes.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn, 16, = 19); > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0 } > +=A0=A0=A0 else if ((9 =3D=3D > arm_insn_r->opcode) || (13 =3D=3D arm_insn_r->opcode) > +=A0=A0=A0=A0=A0 || (0 =3D=3D arm_insn_r->opcode) || (4 =3D=3D arm_insn_r= ->opcode)) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* 4) Store, register pre-indexed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 /* 6) Store, register post -indexed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 0, 3); > +=A0=A0=A0=A0=A0=A0=A0 reg_src2 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0=A0=A0=A0=A0 regcache_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=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=A0=A0 regcache_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=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 /* Calculate target store address, Rn +/- Rm, regi= ster offset.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if ((13 =3D=3D arm_insn_r->opcode) || (4 =3D=3D ar= m_insn_r->opcode)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsigned_reg= val + u_buf[1].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > + > else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[1].unsigned_reg= val - u_buf[0].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 /* Record Rn also as it changes.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn, 16, = 19); > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > + > } > +=A0=A0=A0 /* DSP insns=A0 (e.g. LDRD)=A0 TBD.=A0 */ > +=A0 } > +=A0 else if ((1 =3D=3D arm_insn_r->decode) && (0x12 =3D=3D opcode1) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && sbo_sbz (arm_insn_r->arm_insn, 9, 12, = 1)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle BX, branch and link/exchange.=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 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if ((1 =3D=3D arm_insn_r->decode) && (0x16 =3D=3D opcode1) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && sbo_sbz (arm_insn_r->arm_insn, 9, 4, 1) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 && sbo_sbz > (arm_insn_r->arm_insn, 17, 4, 1)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Count leading zeros: CLZ.=A0 */ > +=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (!bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 && ((8 =3D=3D arm_insn_r->opcode) || (10 =3D= =3D arm_insn_r->opcode)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 && sbo_sbz (arm_insn_r->arm_insn, 17, 4, 1) > +=A0=A0=A0=A0=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=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle MRS insn.=A0 */ > + > record_buf[0] =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (arm_insn_r->opcode <=3D 15) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Normal data processing insns.=A0 */ > +=A0=A0=A0=A0=A0 /* Out of 11 shifter operands mode, all the insn modifie= s destination > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register, which is specifi= ed by 13-16 decode.=A0 */ > +=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0 } > +=A0 else > + > { > +=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_b= uf); > +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_b= uf_mem); > +=A0 return 0; > +} > + > +/* Handling opcode 001 insns.=A0 */ > + > +static int > +arm_handle_data_proc_imm_insn (insn_decode_record *arm_insn_r) > +{ > +=A0 uint32_t record_buf[8], record_buf_mem[8]; > + > +=A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); > +=A0 arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); > + > +=A0 if (((9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_insn_r->opcode)) > +=A0=A0=A0=A0=A0=A0 && (2 =3D=3D bits (arm_insn_r->arm_insn, 20, 21)) > +=A0=A0=A0=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=A0=A0=A0 if (9 =3D=3D arm_insn_r->opcode) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /*CSPR is going to be changed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* SPSR is going to be changed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if (arm_insn_r->opcode <=3D 15) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Normal data > processing insns.=A0 */ > +=A0=A0=A0=A0=A0 /* Out of 11 shifter operands mode, all the insn modifie= s destination > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register, which is specifi= ed by 13-16 decode.=A0 */ > +=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_b= uf); > +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_b= uf_mem); > +=A0 return 0; > +} > + > +/* Handling opcode 010 insns. > */ > + > +static int > +arm_handle_ld_st_imm_offset_insn (insn_decode_record *arm_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D arm_insn_r->regcache; > + > +=A0 uint32_t reg_src1 =3D 0 , reg_dest =3D 0; > +=A0 uint32_t offset_12 =3D 0, tgt_mem_addr =3D 0; > +=A0 uint32_t record_buf[8], record_buf_mem[8]; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 memset (&u_buf, 0, sizeof (u_buf)); > +=A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); > +=A0 arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); > + > +=A0 if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 reg_dest =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 /* LDR insn has a capability to do branching, > if > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 MOV LR, PC is precedded by LDR i= nsn having Rn as R15 > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 in that case, it emulates branch= and link insn, and hence we > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 need to save CSPR and PC as well= .=A0 */ > +=A0=A0=A0=A0=A0 if (15 !=3D reg_dest) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn= , 12, 15); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D > reg_dest; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Store, immediate offset, immediate pre-indexed, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 immediate post-indexed.=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0=A0=A0 offset_12 =3D bits (arm_insn_r->arm_insn, 0, 11); > +=A0=A0=A0=A0=A0 regcache_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=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=A0 if (bit (arm_insn_r->arm_insn, 23)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf.unsigned_regval + off= set_12; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else > +=A0=A0=A0=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=A0=A0 switch (arm_insn_r->opcode) > + > { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 8: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 12: > +=A0 =A0=A0=A0 =A0=A0=A0=A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 9: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 13: > +=A0=A0=A0 =A0=A0=A0=A0 /* STRT */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 1: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 5: > +=A0=A0=A0 =A0=A0=A0=A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 4: > +=A0 =A0=A0=A0 =A0=A0=A0=A0 case 0: > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR insn, STRT insn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0 =A0=A0=A0=A0 /* STRB */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 10: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 14: > +=A0=A0=A0 =A0=A0=A0=A0 /* STRB */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 11: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 15: > +=A0=A0=A0 =A0=A0=A0=A0 /* STRBT */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 3: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 case > 7: > +=A0=A0=A0 =A0=A0=A0=A0 /* STRB */ > +=A0=A0=A0 =A0=A0=A0=A0 case 2: > +=A0=A0=A0 =A0=A0=A0=A0 case 6: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STRB insn, STRBT insn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 default: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > + > arm_insn_r->mem_rec_count =3D 1; > + > +=A0=A0=A0=A0=A0 if ((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=A0=A0=A0 /* We are handling pre-indexed mode; post-in= dexed > mode; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_b= uf); > +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_b= uf_mem); > +=A0 return 0; > +} > + > +/* Handling opcode 011 insns.=A0 */ > + > +static int > +arm_handle_ld_st_reg_offset_insn (insn_decode_record *arm_insn_r) > +{ > +=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, reg_dest =3D 0; > +=A0 uint32_t immed_high =3D 0, immed_low =3D 0, offset_12 =3D 0, tgt_mem= _addr =3D 0; > +=A0 uint32_t record_buf[8], record_buf_mem[8]; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 LONGEST signed_word; > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf[2]; > + > +=A0 memset (&u_buf, 0, sizeof (u_buf)); > +=A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 21, 24); > +=A0 arm_insn_r->decode =3D bits (arm_insn_r->arm_insn, 4, 7); > + > +=A0 /* Handle enhanced store insns and LDRD DSP insn, > +=A0=A0=A0=A0=A0=A0=A0 let us begin according to addressing modes for sto= re insns > +=A0=A0=A0=A0=A0=A0=A0 STRH insn.=A0 */ > + > +=A0 /* LDR or STR?=A0 */ > +=A0 if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > + > { > +=A0=A0=A0=A0=A0 reg_dest =3D bits (arm_insn_r->arm_insn, 12, 15); > +=A0=A0=A0=A0=A0 /* LDR insn has a capability to do branching, if > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 MOV LR, PC is precedded by LDR i= nsn having Rn as R15 > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 in that case, it emulates branch= and link insn, and hence we > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 need to save CSPR and PC as well= .=A0 */ > +=A0=A0=A0=A0=A0 if (15 !=3D reg_dest) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->arm_insn= , 12, 15); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > + > } > +=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D reg_dest; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 if (! bits (arm_insn_r->arm_insn, 4, 11)) > +=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 re= gister post-indexed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Get > Rm.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 0, = 3); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Get Rn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src2 =3D bits (arm_insn_r->arm_insn, 16,= 19); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_raw_read_unsigned (reg_cache, reg_s= rc1 > +=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=A0=A0=A0=A0=A0=A0=A0 , &u_buf[0].unsigned_regval); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_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=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 if (15 =3D=3D reg_src2) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0 /* Pre-indexed mode doesnt reach= here ; illegal insn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 u_buf[0].unsigned_regval =3D > u_buf[0].unsigned_regval + 8; > +=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0 /* U =3D=3D 1.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (bit (arm_insn_r->arm_insn, 23)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[0].unsign= ed_regval + > +=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 u_buf[1].unsigned_regval; > + > } > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[1].unsign= ed_regval - > +=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 u_buf[0].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 switch (arm_insn_r->opcode) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case > 8: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 12: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 9: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 13: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STRT */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 1: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 5: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STR */ > +=A0=A0=A0 =A0=A0=A0 =A0 case 0: > +=A0=A0=A0 =A0=A0=A0 =A0 case > 4: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR insn, STRT insn.=A0= */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STRB */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 10: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 14: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STRB */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 11: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 15: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STRBT */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 3: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 7: > +=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0 =A0 /* STRB */ > +=A0=A0=A0 =A0=A0=A0 =A0 case 2: > +=A0=A0=A0 =A0=A0=A0 =A0 case 6: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STRB insn, STRBT insn.= =A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > + > default: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D 1; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if ((9 =3D=3D arm_insn_r->opcode) || (11 =3D= =3D arm_insn_r->opcode) > +=A0=A0=A0=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=A0=A0=A0 || (0 =3D=3D arm_insn_r->opcode) || (2 =3D= =3D arm_insn_r->opcode) > +=A0=A0=A0=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=A0=A0=A0 || (1 =3D=3D arm_insn_r->opcode) || (3 =3D= =3D arm_insn_r->opcode) > +=A0=A0=A0=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=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=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 post-indexed mode as well.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src2; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Store insn, scaled register offset; scale= d pre-indexed.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset_12 =3D bits (arm_insn_r->arm_insn, 5,= 6); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Get Rm.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 0, = 3); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Get Rn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src2 =3D bits (arm_insn_r->arm_insn, 16, > 19); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Get shift_imm.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 shift_imm =3D bits (arm_insn_r->arm_insn, 7,= 11); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_raw_read_unsigned (reg_cache, reg_s= rc1 > +=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=A0=A0=A0=A0=A0=A0=A0 , &u_buf[0].unsigned_regval); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_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=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=A0=A0=A0=A0 regcache_raw_read_unsigned (reg_cache, reg_s= rc2 > +=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=A0=A0=A0=A0=A0=A0=A0 , &u_buf[1].unsigned_regval); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Offset_12 used as shift.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 switch (offset_12) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 0: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Offset_12 used as index. > */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset_12 =3D u_buf[0].uns= igned_regval << shift_imm; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 1: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset_12 =3D (!shift_imm)= ?0:u_buf[0].unsigned_regval >> shift_imm; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 2: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if > (!shift_imm) > +=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=A0=A0=A0=A0=A0=A0 if (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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 of= fset_12 =3D 0xFFFFFFFF; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > + > else > +=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 of= fset_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=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 else > +=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=A0=A0=A0=A0=A0=A0 /* This is ari= thmetic shift. > */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset_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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 3: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (!shift_imm) > +=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=A0=A0=A0=A0=A0=A0 regcache_raw_r= ead_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=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=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=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset_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=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 else > +=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=A0=A0=A0=A0=A0=A0 offset_12 =3D = (u_buf[0].unsigned_regval >> shift_imm) \ > +=A0=A0=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 << (sizeof(uint32_t) - shift_imm)); > + > } > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 default: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_raw_read_unsigned (reg_cache, reg_s= rc2 > +=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=A0=A0=A0=A0=A0=A0=A0 , &u_buf[1].unsigned_regval); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* U =3D=3D 1 > */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (bit (arm_insn_r->arm_insn, 23)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[1].unsign= ed_regval + offset_12; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tgt_mem_addr =3D u_buf[1].unsign= ed_regval - offset_12; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 switch > (arm_insn_r->opcode) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 8: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 12: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STR */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 9: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 13: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STRT */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 1: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case > 5: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STR */ > +=A0=A0=A0 =A0=A0=A0 =A0 case 0: > +=A0=A0=A0 =A0=A0=A0 =A0 case 4: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR insn, STRT insn.=A0= */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STRB */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 10: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 14: > + > =A0=A0=A0 =A0 /* STRB */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 11: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 15: > +=A0=A0=A0 =A0=A0=A0 =A0 /* STRBT */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 3: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 case 7: > +=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0 =A0 /* STRB */ > +=A0=A0=A0 =A0=A0=A0 =A0 case 2: > +=A0=A0=A0 =A0=A0=A0 =A0 case 6: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STRB insn, STRBT insn. > */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 default: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 break; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D tgt_mem_addr; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D > 1; > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if ((9 =3D=3D arm_insn_r->opcode) || (11 =3D= =3D arm_insn_r->opcode) > +=A0=A0=A0=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=A0=A0=A0 || (0 =3D=3D arm_insn_r->opcode) || (2 =3D= =3D arm_insn_r->opcode) > +=A0=A0=A0=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=A0=A0=A0 || (1 =3D=3D arm_insn_r->opcode) || (3 =3D= =3D arm_insn_r->opcode) > +=A0=A0=A0=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=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=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 mode, and scaled post indexed mode.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src2; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > + > +=A0 REG_ALLOC > (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf); > +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_b= uf_mem); > +=A0 return 0; > +} > + > +/* Handling opcode 100 insns.=A0 */ > + > +static int > +arm_handle_ld_st_multiple_insn (insn_decode_record *arm_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D arm_insn_r->regcache; > + > +=A0 uint32_t register_list[16] =3D {0}, register_count =3D 0, register_b= its =3D 0; > +=A0 uint32_t shift_imm =3D 0; > +=A0 uint32_t reg_src1 =3D 0, reg_src2 =3D 0, addr_mode =3D 0, no_of_regs= =3D 0; > +=A0 uint32_t start_address =3D 0, index =3D 0; > +=A0 uint32_t record_buf[24], record_buf_mem[48]; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf[2]; > + > +=A0 memset (&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=A0=A0=A0=A0 Rn is changing depending on W bit, but as of now w= e store Rn too without optmization.=A0 */ > + > +=A0 if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* LDM=A0 (1,2,3) where LDM=A0 (3) changes CPSR too.=A0 = */ > + > +=A0=A0=A0=A0=A0 if (bit (arm_insn_r->arm_insn,20) && !bit (arm_insn_r->a= rm_insn,22)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D bits (arm_insn_r->arm_insn= , 0, 15); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 no_of_regs =3D 15; > +=A0=A0=A0=A0=A0=A0=A0 } > + > else > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D bits (arm_insn_r->arm_insn= , 0, 14); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 no_of_regs =3D 14; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 /* Get Rn.=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0=A0=A0 while (register_bits) > +=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0 if (register_bits & 0x00000001) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_list[register_count++] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D register_bits >> 1; > +=A0=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0=A0=A0=A0=A0 /* Extra space for > Base Register and CPSR; wihtout optmization.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 record_buf[register_count] =3D reg_src1; > +=A0=A0=A0=A0=A0=A0=A0 record_buf[register_count + 1] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->reg_rec_count =3D register_count + 2; > + > +=A0=A0=A0=A0=A0=A0=A0 for (register_count =3D 0; register_count < no_of_= regs; register_count++) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if=A0 (register_list[register_count]) > +=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 /* Register_count gives total no= of registers and dually working > +=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 as reg number.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[index] =3D regi= ster_count; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 index++; > +=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 else > +=A0=A0=A0 { > +=A0=A0=A0 /* It handles both STM(1) and STM(2).=A0 */ > +=A0=A0=A0 addr_mode =3D bits (arm_insn_r->arm_insn, 23, 24); > + > +=A0=A0=A0 register_bits =3D bits (arm_insn_r->arm_insn, 0, 15); > +=A0=A0=A0 /* > Get Rn.=A0 */ > +=A0=A0=A0 reg_src1 =3D bits (arm_insn_r->arm_insn, 16, 19); > +=A0=A0=A0 regcache_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=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 , &u_buf[0].unsigned_regval); > +=A0=A0=A0 while (register_bits) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 if (register_bits & 0x00000001) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count++; > +=A0=A0=A0=A0=A0=A0=A0 register_bits =3D register_bits >> 1; > +=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0 switch (addr_mode) > +=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* Decrement after.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 case 0: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D (u_buf[0].unsigned_regval)= - (register_count * 4) + 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D register_count; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 while (register_count) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 1] =3D start_address; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 2] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D start_address + > 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count--; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0 /* Increment after.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 case 1: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D u_buf[0].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D register_count; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 while (register_count) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 1] =3D > start_address; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 2] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D start_address = + 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count--; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0 /* Decrement before.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 case 2: > + > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D (u_buf[0].unsigned_regval)= - (register_count * 4); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D > register_count; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 while (register_count) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 1] =3D start_address; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 2] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D start_address = + 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count--; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0 /* Increment before.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 case > 3: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D u_buf[0].unsigned_regval += 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 arm_insn_r->mem_rec_count =3D register_count; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 while (register_count) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 1] =3D start_address; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count *= 2) - 2] =3D 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D start_address = + 4; > + > register_count--; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 break; > + > +=A0=A0=A0=A0=A0=A0=A0 default: > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0 break; > +=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0 /* Base register also changes; based on condition and W bit.= =A0 */ > +=A0=A0=A0 /* We save it anyway without optimization.=A0 */ > +=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0 arm_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_b= uf); > +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_b= uf_mem); > +=A0 return 0; > +} > + > +/* Handling opcode > 101 insns.=A0 */ > + > +static int > +arm_handle_brn_insn (insn_decode_record *arm_insn_r) > +{ > + > +=A0 uint32_t record_buf[8]; > + > +=A0 /* Handle B, BL, BLX(1) insns.=A0 */ > +=A0 /* Wihtout optmization we save link register, > +=A0=A0=A0=A0=A0=A0=A0 CSPR for the insn which changes T bit.=A0 */ > +=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0 record_buf[1] =3D ARM_LR_REGNUM; > +=A0 arm_insn_r->reg_rec_count =3D 2; > + > +=A0 REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_b= uf); > + > +=A0 return 0; > +} > + > +/* Handling opcode 110 insns.=A0 */ > + > +static int > +arm_handle_coproc_insn (insn_decode_record *arm_insn_r) > +{ > +=A0 printf_unfiltered (_("Process record does not support instruction > " > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "0x%0x at a= ddress %s.\n"), > +=A0=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0=A0=A0=A0 paddress (a= rm_insn_r->gdbarch, arm_insn_r->this_addr)); > + > +=A0=A0 return -1; > +} > + > +/* Handling opcode 111 insns.=A0 */ > + > +static int > +arm_handle_coproc_data_proc_insn (insn_decode_record *arm_insn_r) > +{ > +=A0=A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep (arm_insn_r->gdbarch); > +=A0=A0 struct regcache *reg_cache =3D arm_insn_r->regcache; > + > +=A0=A0 uint32_t shift_imm =3D 0; > +=A0=A0 uint32_t reg_src1 =3D 0, reg_src2 =3D 0, addr_mode =3D > 0; > +=A0=A0 uint32_t start_address =3D 0; > + > +=A0=A0 /* Handle SWI insn; system call would be handled over here.=A0 */ > + > +=A0=A0 arm_insn_r->opcode =3D bits (arm_insn_r->arm_insn, 24, 27); > +=A0=A0 if (15 =3D=3D arm_insn_r->opcode) > +=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* Handle arm syscall insn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if (tdep->arm_swi_record !=3D NULL) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tdep->arm_swi_record(reg_cache); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 else > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf_unfiltered (_("no syscall record > support\n")); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=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=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=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr)); > +=A0=A0 return -1; > +} > + > +/* Handling opcode 000 insns.=A0 */ > + > +static int > +thumb_handle_shift_add_sub_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 uint32_t record_buf[8]; > +=A0 uint32_t reg_src1 =3D 0; > + > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); > + > +=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0 record_buf[1] =3D reg_src1; > +=A0 thumb_insn_r->reg_rec_count =3D 2; > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > + > +=A0 return 0; > +} > + > + > +/* Handling opcode 001 insns.=A0 */ > + > +static int > +thumb_handle_add_sub_cmp_mov_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 uint32_t record_buf[8]; > +=A0 uint32_t reg_src1 =3D 0; > + > +=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > + > +=A0 record_buf[0] =3D > ARM_PS_REGNUM; > +=A0 record_buf[1] =3D reg_src1; > +=A0 thumb_insn_r->reg_rec_count =3D 2; > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > + > +=A0 return 0; > +} > + > +/* Handling opcode 010 insns.=A0 */ > + > +static int > +thumb_handle_ld_st_reg_offset_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D=A0 thumb_insn_r->regcache; > +=A0 uint32_t record_buf[8], record_buf_mem[8]; > + > +=A0 uint32_t reg_src1 =3D 0, reg_src2 =3D 0; > +=A0 uint32_t opcode1 =3D 0, opcode2 =3D 0, opcode3 =3D 0; > + > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0=A0=A0 gdb_byte buf[4]; > +=A0=A0=A0 } u_buf[2]; > + > +=A0 opcode1 =3D bits (thumb_insn_r->arm_insn, 10, 12); > + > +=A0 if (bit (thumb_insn_r->arm_insn, > 12)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle load/store register offset.=A0 */ > +=A0=A0=A0=A0=A0 opcode2 =3D bits (thumb_insn_r->arm_insn, 9, 10); > +=A0=A0=A0=A0=A0 if ((opcode2 >=3D 12) && (opcode2 <=3D 15)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH.= =A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn,0,= 2); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else if ((opcode2 >=3D 8) > && (opcode2 <=3D 10)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* STR(2), STRB(2), STRH(2) .=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 3= , 5); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src2 =3D bits (thumb_insn_r->arm_insn, 6= , 8); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_raw_read_unsigned (reg_cache, reg_s= rc1 > +=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=A0=A0=A0=A0=A0=A0=A0 , &u_buf[0].unsigned_regval); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_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=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 if (8 =3D=3D opcode2) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 4;=A0=A0=A0 /* S= TR (2).=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 else if (10 =3D=3D opcode2) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 1;=A0=A0=A0 /*= =A0 STRB (2).=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 else if (9 =3D=3D opcode2) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[0] =3D > 2;=A0=A0=A0 /* STRH (2).=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[1] =3D u_buf[0].unsigned_regv= al+u_buf[1].unsigned_regval; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 thumb_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if (bit (thumb_insn_r->arm_insn, 11)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Handle load from literal pool.=A0 */ > +=A0=A0=A0=A0=A0 /* LDR(3).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > +=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (opcode1) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 opcode2 =3D bits (thumb_insn_r->arm_insn, 8, 9); > +=A0=A0=A0=A0=A0 opcode3 =3D bits (thumb_insn_r->arm_insn, 0, 2); > +=A0=A0=A0=A0=A0 if ((3 =3D=3D opcode2) && (!opcode3)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Branch with exchange.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 else > + > { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Format 8; special data processing insns.= =A0 */ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 0= , 2); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D reg_src1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Format 5; data processing insns.=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); > +=A0=A0=A0=A0=A0 if (bit (thumb_insn_r->arm_insn, 7)) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 reg_src1 > =3D reg_src1 + 8; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 record_buf[1] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, reco= rd_buf_mem); > + > +=A0 return 0; > +} > + > +/* Handling opcode 001 insns.=A0 */ > + > +static int > +thumb_handle_ld_st_imm_offset_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D thumb_insn_r->regcache; > +=A0 uint32_t record_buf[8], record_buf_mem[8]; > + > +=A0 uint32_t reg_val1 =3D 0; > +=A0 uint32_t reg_src1 =3D 0; > +=A0 uint32_t opcode =3D 0, immed_5 =3D 0; > + > + > struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); > + > +=A0 if (opcode) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* LDR(1).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, 2); > +=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* STR(1).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 3, 5); > +=A0=A0=A0=A0=A0 immed_5 =3D bits (thumb_insn_r->arm_insn, 6, 10); > +=A0=A0=A0=A0=A0 regcache_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=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 , &u_buf.unsigned_regval); > +=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 4; > +=A0=A0=A0=A0=A0 record_buf_mem[1] =3D u_buf.unsigned_regval + (immed_5 *= 4); > +=A0=A0=A0=A0=A0 thumb_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, reco= rd_buf_mem); > + > +=A0 return 0; > +} > + > +/* Handling opcode 100 insns.=A0 */ > + > +static int > +thumb_handle_ld_st_stack_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D thumb_insn_r->regcache; > +=A0 uint32_t > record_buf[8], record_buf_mem[8]; > + > +=A0 uint32_t reg_val1 =3D 0; > +=A0 uint32_t reg_src1 =3D 0; > +=A0 uint32_t opcode =3D 0, immed_8 =3D 0, immed_5 =3D 0; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); > + > +=A0 if (3 =3D=3D opcode) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* LDR(4).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > +=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (1 =3D=3D opcode) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* LDRH(1).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 0, > 2); > +=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (2 =3D=3D opcode) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* STR(3).=A0 */ > +=A0=A0=A0=A0=A0 immed_8 =3D bits (thumb_insn_r->arm_insn, 0, 7); > +=A0=A0=A0=A0=A0 regcache_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=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 record_buf_mem[0] =3D 4; > +=A0=A0=A0=A0=A0 record_buf_mem[1] =3D u_buf.unsigned_regval + (immed_8 *= 4); > +=A0=A0=A0=A0=A0 thumb_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (0 =3D=3D > opcode) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* STRH(1).=A0 */ > +=A0=A0=A0=A0=A0 immed_5 =3D bits (thumb_insn_r->arm_insn, 6, 10); > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 3, 5); > +=A0=A0=A0=A0=A0 regcache_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=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 , &u_buf.unsigned_regval); > +=A0=A0=A0=A0=A0 record_buf_mem[0] =3D 2; > +=A0=A0=A0=A0=A0 record_buf_mem[1] =3D u_buf.unsigned_regval + (immed_5 *= 2); > +=A0=A0=A0=A0=A0 thumb_insn_r->mem_rec_count =3D 1; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > +=A0 MEM_ALLOC > (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, record_buf_mem); > + > +=A0 return 0; > +} > + > +/* Handling opcode 101 insns.=A0 */ > + > +static int > +thumb_handle_misc_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 struct regcache *reg_cache =3D thumb_insn_r->regcache; > + > +=A0 uint32_t reg_val1 =3D 0; > +=A0 uint32_t reg_src1 =3D 0; > +=A0 uint32_t opcode =3D 0, opcode1 =3D 0, opcode2 =3D 0, immed_8 =3D 0, = immed_5 =3D 0; > +=A0 uint32_t register_bits =3D 0, register_count =3D 0; > +=A0 uint32_t register_list[8] =3D {0}, index =3D 0, start_address =3D 0; > +=A0 uint32_t record_buf[24], record_buf_mem[48]; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 opcode =3D bits (thumb_insn_r->arm_insn, 11, 12); > +=A0 opcode1 =3D bits (thumb_insn_r->arm_insn, 8, 12); > +=A0 opcode2 =3D > bits (thumb_insn_r->arm_insn, 9, 12); > + > +=A0 if (14 =3D=3D opcode2) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* POP.=A0 */ > +=A0=A0=A0=A0=A0 register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); > +=A0=A0=A0=A0=A0 while (register_bits) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (register_bits & 0x00000001) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_list[register_count++] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D register_bits >> 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 record_buf[register_count] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 record_buf[register_count + 1] =3D ARM_SP_REGNUM; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D register_count + > 2; > +=A0=A0=A0=A0=A0 for (register_count =3D 0; register_count < 8; register_= count++) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if=A0 (register_list[register_count]) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[index] =3D register_c= ount; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 index++; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if (10 =3D=3D opcode2) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* PUSH.=A0 */ > +=A0=A0=A0=A0=A0 register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); > +=A0=A0=A0=A0=A0 regcache_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=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 while (register_bits) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (register_bits & 0x00000001) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count++; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D register_bits >> 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 start_address =3D u_buf.unsigned_regval -=A0 \ > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 (4 * (bit (thumb_= insn_r->arm_insn, 8) + register_count)) > ; > +=A0=A0=A0=A0=A0 thumb_insn_r->mem_rec_count =3D register_count; > +=A0=A0=A0=A0=A0 while (register_count) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count * 2) - 1] =3D= start_address; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count * 2) - 2] =3D= 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D start_address + 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count--; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_SP_REGNUM; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (0x1E =3D=3D opcode1) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* BKPT insn. > */ > +=A0=A0=A0=A0=A0 /* Handle enhanced software breakpoint insn, BKPT.=A0 */ > +=A0=A0=A0=A0=A0 /* CPSR is changed to be executed in ARM state,=A0 disab= ling normal > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 interrupts, entering abort mo= de.=A0 */ > +=A0=A0=A0=A0=A0 /* Accorindly to high vector configuration PC is set acc= ordingly.=A0 */ > +=A0=A0=A0=A0=A0 /* FIX ME ?=A0 what if user hit breakpoint and type reve= rse, in > +=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0=A0=A0 Program Counter..=A0 */ > +=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0=A0=A0=A0=A0 record_buf[1] =3D > ARM_LR_REGNUM; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 2; > +=A0=A0=A0=A0=A0 /* Save SPSR also; how?.=A0 */ > +=A0=A0=A0=A0=A0 printf_unfiltered (_("Process record does not support in= struction " > +=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 "0x%0x at address %s.\n"), > +=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 thumb_insn_r->arm_insn, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 paddress (t= humb_insn_r->gdbarch, thumb_insn_r->this_addr)); > +=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0 } > +=A0 else if ((0 =3D=3D opcode) || (1 =3D=3D opcode)) > + > { > +=A0=A0=A0=A0=A0=A0 /* ADD(5), ADD(6).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > +=A0=A0=A0=A0=A0 record_buf[0] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > +=A0 else if (2 =3D=3D opcode) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* ADD(7), SUB(4).=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > +=A0=A0=A0=A0=A0 record_buf[0] =3D ARM_SP_REGNUM; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D 1; > +=A0=A0=A0 } > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, reco= rd_buf_mem); > + > +=A0 return 0; > +} > + > +/* Handling opcode 110 > insns.=A0 */ > + > +static int > +thumb_handle_swi_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 struct gdbarch_tdep *tdep =3D gdbarch_tdep (thumb_insn_r->gdbarch); > +=A0 struct regcache *reg_cache =3D thumb_insn_r->regcache; > + > +=A0 uint32_t reg_val1 =3D 0; > +=A0 uint32_t reg_src1 =3D 0; > +=A0 uint32_t opcode1 =3D 0, opcode2 =3D 0, register_bits =3D 0, register= _count =3D 0; > +=A0 uint32_t register_list[8] =3D {0}, index =3D 0, start_address =3D 0; > +=A0 uint32_t record_buf[24], record_buf_mem[48]; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 opcode1 =3D bits (thumb_insn_r->arm_insn, 8, 12); > +=A0 opcode2 =3D bits (thumb_insn_r->arm_insn, 11, 12); > + > +=A0 if (1 =3D=3D opcode2) > + > { > + > +=A0=A0=A0=A0=A0 /* LDMIA.=A0 */ > +=A0=A0=A0=A0=A0 register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); > +=A0=A0=A0=A0=A0 /* Get Rn.=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits (thumb_insn_r->arm_insn, 8, 10); > +=A0=A0=A0=A0=A0 while (register_bits) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (register_bits & 0x00000001) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_list[register_count++] =3D 1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D register_bits >> 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 record_buf[register_count] =3D reg_src1; > +=A0=A0=A0=A0=A0 thumb_insn_r->reg_rec_count =3D register_count + 1; > +=A0=A0=A0=A0=A0 for > (register_count =3D 0; register_count < 8; register_count++) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (register_list[register_count]) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[index] =3D register_c= ount; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 index++; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if (0 =3D=3D opcode2) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* It handles both STMIA.=A0 */ > +=A0=A0=A0=A0=A0 register_bits =3D bits (thumb_insn_r->arm_insn, 0, 7); > +=A0=A0=A0=A0=A0 /* Get Rn.=A0 */ > +=A0=A0=A0=A0=A0 reg_src1 =3D bits > (thumb_insn_r->arm_insn, 8, 10); > +=A0=A0=A0=A0=A0 regcache_raw_read_unsigned (reg_cache, reg_src1, &u_buf.= unsigned_regval); > +=A0=A0=A0=A0=A0 while (register_bits) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (register_bits & 0x00000001) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count++; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_bits =3D register_bits >> 1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 start_address =3D u_buf.unsigned_regval; > +=A0=A0=A0=A0=A0 thumb_insn_r->mem_rec_count =3D register_count; > +=A0=A0=A0=A0=A0 while (register_count) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count * 2) - 1] =3D > start_address; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf_mem[(register_count * 2) - 2] =3D= 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 start_address =3D start_address + 4; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 register_count--; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if (0x1F =3D=3D opcode1) > +=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0 /* Handle arm syscall insn.=A0 */ > +=A0=A0=A0=A0=A0=A0=A0 if (tdep->arm_swi_record !=3D NULL) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 tdep->arm_swi_record(reg_cache); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 else > + > { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf_unfiltered (_("no syscall recor= d support\n")); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0 } > + > +=A0 /* B(1), conditional branch is automatically taken care in process_r= ecord, > +=A0=A0=A0=A0=A0=A0=A0 as PC is saved there.=A0 */ > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, reco= rd_buf_mem); > + > +=A0 return 0; > +} > + > +/* Handling opcode 111 insns.=A0 */ > + > +static int > +thumb_handle_branch_insn (insn_decode_record *thumb_insn_r) > +{ > +=A0 uint32_t record_buf[8]; > +=A0 uint32_t reg_val1 =3D 0; > +=A0 uint32_t reg_src1 =3D 0; > + > uint32_t opcode =3D 0, immed_5 =3D 0; > + > + > +=A0 /* BL , BLX(1).=A0 */ > +=A0 record_buf[0] =3D ARM_PS_REGNUM; > +=A0 record_buf[1] =3D ARM_LR_REGNUM; > +=A0 thumb_insn_r->reg_rec_count =3D 2; > + > +=A0 /* B(2) is automatically taken care in process_record, as PC is saved > +=A0=A0=A0=A0=A0=A0=A0 there.=A0 */ > + > +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, reco= rd_buf); > + > +=A0 return 0; > +} > + > + > +/* Decode arm/thumb insn depending on condition cods and opcodes; and di= spatch 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 */ > +=A0 static 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=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=A0=A0=A0 arm_handle_data_proc_misc_ld_str_insn,=A0=A0=A0 /* 000.= =A0 */ > +=A0=A0=A0=A0=A0 arm_handle_data_proc_imm_insn,=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 /* 001.=A0 */ > +=A0=A0=A0=A0=A0 arm_handle_ld_st_imm_offset_insn,=A0=A0=A0=A0=A0=A0=A0= =A0 /* 010.=A0 */ > +=A0=A0=A0=A0=A0 arm_handle_ld_st_reg_offset_insn,=A0=A0=A0=A0=A0=A0=A0= =A0 /* 011.=A0 */ > +=A0=A0=A0=A0=A0 arm_handle_ld_st_multiple_insn,=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 /* 100. > */ > +=A0=A0=A0=A0=A0 arm_handle_brn_insn,=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 /* 101.=A0 */ > +=A0=A0=A0=A0=A0 arm_handle_coproc_insn,=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 /* 110.=A0 */ > +=A0=A0=A0=A0=A0 arm_handle_coproc_data_proc_insn=A0=A0=A0=A0=A0=A0=A0=A0= =A0 /* 111.=A0 */ > +=A0 }; > + > +=A0 /* (Starting from numerical 0); bits 13,14,15 decodes type of thumb = instruction.=A0 */ > +=A0 static int (*const thumb_handle_insn[8]) > + > (insn_decode_record*) =3D > +=A0 { \ > +=A0=A0=A0=A0=A0 thumb_handle_shift_add_sub_insn,=A0=A0=A0=A0=A0=A0=A0=A0= /* 000.=A0 */ > +=A0=A0=A0=A0=A0 thumb_handle_add_sub_cmp_mov_insn,=A0=A0=A0=A0=A0=A0 /* = 001.=A0 */ > +=A0=A0=A0=A0=A0 thumb_handle_ld_st_reg_offset_insn,=A0=A0=A0=A0=A0 /* 01= 0.=A0 */ > +=A0=A0=A0=A0=A0 thumb_handle_ld_st_imm_offset_insn,=A0=A0=A0=A0=A0 /* 01= 1.=A0 */ > +=A0=A0=A0=A0=A0 thumb_handle_ld_st_stack_insn,=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 /* 100.=A0 */ > +=A0=A0=A0=A0=A0 thumb_handle_misc_insn,=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0 /* 101.=A0 */ > + > thumb_handle_swi_insn,=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 /* 110.=A0 */ > +=A0=A0=A0=A0=A0 thumb_handle_branch_insn=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0 /* 111.=A0 */ > +=A0 }; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 gdb_byte buf[insn_size]; > +=A0=A0=A0 } u_buf; > + > +=A0 uint32_t ret=3D0, insn_id =3D 0; > + > +=A0 memset (&u_buf, 0, sizeof(u_buf)); > +=A0 if (target_read_memory (arm_record->this_addr, &u_buf.buf[0], insn_s= ize)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 if (record_debug) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 printf_unfiltered > (_("Process record: error reading memory at " > +=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 "addr %s len =3D %d.\n"), > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 paddress (arm_record->gdbarch, arm_record->t= his_addr), insn_size); > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 return -1; > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0 } > +=A0 else if (ARM_INSN_SIZE_BYTES =3D=3D insn_size) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 arm_record->arm_insn =3D (uint32_t) extract_unsigned_int= eger (&u_buf.buf[0] > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 , ARM_INSN_SIZE_BYTES , gdbarch_byt= e_order (arm_record->gdbarch)); > +=A0=A0=A0=A0=A0 arm_record->cond =3D bits (arm_record->arm_insn, 28, > 31); > +=A0=A0=A0=A0=A0 insn_id =3D bits (arm_record->arm_insn, 25, 27); > +=A0=A0=A0=A0=A0 ret =3D (0x0F !=3D arm_record->cond) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ? arm_handle_insn[insn_id] (arm_record) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 : handle_extension_space (arm_record); > +=A0=A0=A0 } > +=A0 else if (THUMB_INSN_SIZE_BYTES =3D=3D insn_size) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* As thumb does not have condition codes, following fie= ld is useless.=A0 */ > +=A0=A0=A0=A0=A0 arm_record->cond =3D -1; > +=A0=A0=A0=A0=A0 arm_record->arm_insn =3D (uint32_t) extract_unsigned_int= eger (&u_buf.buf[0] > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 , THUMB_INSN_SIZE_BYTES , gdbarch_byte_or= der > (arm_record->gdbarch)); > + > +=A0=A0=A0=A0=A0 insn_id =3D bits (arm_record->arm_insn, 13, 15); > +=A0=A0=A0=A0=A0 ret =3D thumb_handle_insn[insn_id] (arm_record); > +=A0=A0=A0 } > +=A0 else if (THUMB2_INSN_SIZE_BYTES =3D=3D insn_size) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Yet to be implemented; handle thumb2 part here.=A0 */ > +=A0=A0=A0=A0=A0 printf_unfiltered (_("Process record does not support in= struction 0x%0x " > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= "at address %s.\n"), > + > arm_record->arm_insn, > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= paddress (arm_record->gdbarch, arm_record->this_addr)); > +=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Throw assertion.=A0 */ > +=A0=A0=A0=A0=A0 gdb_assert (0); > +=A0=A0=A0 } > + > +=A0 return ret; > +} > + > +/* Parse the current instruction and record the values of the registers = and > +=A0=A0 memory that will be changed in current instruction to "record_arc= h_list". > +=A0=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0 CORE_ADDR insn_addr) > +{ > + > +=A0 enum bfd_endian byte_order =3D gdbarch_byte_order (gdbarch); > +=A0 uint32_t no_of_rec =3D 0; > +=A0 uint32_t ret =3D 0; > +=A0 ULONGEST t_bit =3D 0; > + > +=A0 struct > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 ULONGEST unsigned_regval; > +=A0=A0=A0 } u_buf; > + > +=A0 insn_decode_record arm_record; > +=A0 memset (&u_buf, 0, sizeof(u_buf)); > + > +=A0 memset (&arm_record, 0, sizeof (insn_decode_record)); > +=A0 arm_record.regcache =3D regcache; > +=A0 arm_record.this_addr =3D insn_addr; > +=A0 arm_record.gdbarch =3D gdbarch; > + > + > +=A0 if (record_debug > 1) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 fprintf_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=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 "addr =3D %s\n", > +=A0=A0=A0=A0=A0 paddress (gdbarch, arm_record.this_addr)); > +=A0=A0=A0 } > + > +=A0 /* Check the insn, whether it is thumb or arm one.=A0 */ > + > +=A0 t_bit =3D arm_psr_thumb_bit (arm_record.gdbarch); > +=A0 regcache_raw_read_unsigned (arm_record.regcache, 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=A0=A0=A0=A0 , &u_buf.unsigned_regval); > + > +=A0 if (!(u_buf.unsigned_regval & t_bit)) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* We are decoding arm > insn.=A0 */ > +=A0=A0=A0=A0=A0 ret =3D decode_insn (&arm_record, ARM_INSN_SIZE_BYTES); > +=A0=A0=A0 } > +=A0 else > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* We are decoding thumb insn.=A0 */ > +=A0=A0=A0=A0=A0 ret =3D decode_insn (&arm_record, THUMB_INSN_SIZE_BYTES); > +=A0=A0=A0 } > + > +=A0 if (0 =3D=3D ret) > +=A0=A0=A0 { > +=A0=A0=A0=A0=A0 /* Record registers.=A0 */ > +=A0=A0=A0=A0=A0 record_arch_list_add_reg (arm_record.regcache, ARM_PC_RE= GNUM); > +=A0=A0=A0=A0=A0 if (arm_record.arm_regs) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 for (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=A0 if (record_arch_list_add_reg (ar= m_record.regcache \ > +=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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 , (arm_record.arm_re= gs[no_of_rec]))) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0 /* Record memories.=A0 */ > +=A0=A0=A0=A0=A0 if (arm_record.arm_mems) > +=A0=A0=A0=A0=A0=A0=A0 { > +=A0=A0=A0=A0=A0=A0=A0=A0=A0 for (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=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (record_arch_list_add_mem \ > +=A0=A0=A0=A0=A0=A0=A0=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=A0=A0=A0=A0=A0=A0=A0=A0 arm_record.arm_mems[no_of_= rec].len)) > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } > +=A0=A0=A0=A0=A0=A0=A0 } > + > +=A0=A0=A0=A0=A0 if (record_arch_list_add_end ()) > +=A0=A0=A0=A0=A0=A0=A0 ret =3D -1; > +=A0=A0=A0 } > + > +=A0 if (arm_record.arm_regs) > +=A0=A0=A0 xfree (arm_record.arm_regs); > +=A0 if > (arm_record.arm_mems) > +=A0=A0=A0 xfree (arm_record.arm_mems); > + > +=A0 return ret; > +} > diff -urN arm_orig/arm-tdep.h arm_new/arm-tdep.h > --- arm_orig/arm-tdep.h=A0=A0=A0 2011-07-28 09:40:19.000000000 +0530 > +++ arm_new/arm-tdep.h=A0=A0=A0 2011-07-28 09:41:06.000000000 +0530 > @@ -201,6 +201,9 @@ > =A0=A0 /* Return the expected next PC if FRAME is stopped at a syscall > =A0=A0=A0=A0=A0 instruction.=A0 */ > =A0=A0 CORE_ADDR (*syscall_next_pc) (struct frame_info *frame); > + > +=A0=A0 /* Parse swi insn args, sycall record.=A0 */ > +=A0 int (*arm_swi_record) (struct regcache *regcache); > =A0}; > > =A0/* Structures used for displaced stepping.=A0 */ > @@ -331,6 +334,8 @@ > =A0=A0=A0 instruction?=A0 */ > =A0extern int arm_pc_is_thumb (struct gdbarch *, CORE_ADDR); > > +extern int arm_process_record (struct > gdbarch *gdbarch, > +=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 struct regcache *regcache, CORE_ADDR addr); > =A0/* Functions exported from armbsd-tdep.h.=A0 */ > > =A0/* Return the appropriate register set for the core section identified > > > > > ________________________________ > From: Tom Tromey > To: paawan oza > Cc: gdb-patches@sourceware.org; Petr Hluz=EDn > Sent: Wednesday, 13 July 2011 1:29 AM > Subject: Re: [PATCH] arm reversible : > >>>>>> "Oza" =3D=3D paawan oza writes: > > Oza> any more comments are welcome make this patch ok, if ARM person can > Oza> have a look at it it would be great. > > You have submitted this patch many times now and nobody has commented > on the details of the ARM decoding.=A0 I think we should proceed on the > theory that this is simply not going to happen. > > Also, I am not as concerned about the correctness of every detail as I > am about the general maintainability and style of the code.=A0 I expect > there will be bugs; those can be fixed. > > You need a ChangeLog entry.=A0 A patch of this magnitude > should also have > a NEWS entry. > > Some kind of testing would be good.=A0 Do the existing tests in > gdb.reverse work with your port?=A0 If so then I think that is sufficient > > Oza> +=A0 =A0 unsigned int reg_len =3D 0; reg_len =3D LENGTH; \ > > Just write=A0=A0=A0unsigned int reg_len =3D LENGTH; > > Oza> +=A0 =A0 =A0 =A0 REGS =3D (uint32_t*) xmalloc (sizeof(uint32_t) * (r= eg_len)); \ > > Mind the spaces and parens.=A0 Better, use XNEWVEC: > > =A0 =A0 REGS =3D XNEWVEC (uint32_t, reg_len); > > Oza> +=A0 =A0 =A0 =A0 while (reg_len) \ > Oza> +=A0 =A0 =A0 =A0 =A0 { \ > Oza> +=A0 =A0 =A0 =A0 =A0 =A0 REGS[reg_len - 1] =3D RECORD_BUF[reg_len - = 1];=A0 \ > Oza> +=A0 =A0 =A0 =A0 =A0 =A0 reg_len--;=A0 \ > Oza> +=A0 =A0 =A0 =A0 =A0 } \ > > Just use memcpy. > > Oza> +#define > MEM_ALLOC(MEMS,LENGTH,RECORD_BUF) \ > > The same comments apply for this macro. > > Oza> +/* ARM instruction record contains opcode of current insn and execu= tion state > Oza> (before entry to > > Oza> +decode_insn() ), contains list of to-be-modified registers and memo= ry blocks > Oza> (on return from > > Your email got corrupted.=A0 Usually this is some bad MUA setting. > > Oza> +=A0 uint32_t mem_rec_count;=A0 =A0 =A0=A0=A0/* No of mem recors */ > > Typo, "recors" > > Oza> +/* Checks ARM SBZ and SBO mendatory fields.=A0 */ > > Typo, should be "mandatory". > > Oza> +=A0 if(!sbo) > > Spacing. > > Oza> +=A0 if ((3 =3D=3D opcode1) && (bit (arm_insn_r->arm_insn, 4))) > > Over-parenthesizing makes the code harder to read.=A0 Please fix this.=A0= I > noticed it in many places.=A0 This specific case should read: > > =A0 if (3 =3D=3D opcode1 && bit > (arm_insn_r->arm_insn, 4)) > > Oza> +=A0 memset(&u_buf, 0, sizeof (u_buf)); > > Spacing.=A0 Just go through the entire patch and fix all the spacing > issues. > > I feel like I have mentioned this before. > > Oza> +=A0 =A0 =A0 regcache_raw_read_unsigned (reg_cache, reg_src1 > Oza> +=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= , &u_buf[0].unsigned_regval); > > What if this does not return REG_VALID? > There are multiple instances of this. > > Oza> +=A0 =A0 =A0 gdb_assert_not_reached ("no decoding pattern found"); > > It seems wrong to use an assert in this code.=A0 At least, it is not > obvious to me that this represents a logic error in gdb as opposed to a > merely unrecognized instruction.=A0 An unrecognized instruction can occur > for many reasons, e.g., a bad jump. > > Oza> + > =A0 if ((8 =3D=3D arm_insn_r->opcode) || (10 =3D=3D arm_insn_r->opcode) > Oza> +=A0 =A0 =A0 || (12 =3D=3D arm_insn_r->opcode) || (14 =3D=3D arm_ins= n_r->opcode) > Oza> +=A0 =A0 =A0 || (9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_insn= _r->opcode) > Oza> +=A0 =A0 =A0 || (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_ins= n_r->opcode) > Oza> +=A0 =A0 =A0 || (0 =3D=3D arm_insn_r->opcode) || (2 =3D=3D arm_insn_= r->opcode) > Oza> +=A0 =A0 =A0 || (4 =3D=3D arm_insn_r->opcode) || (6 =3D=3D arm_insn_= r->opcode) > Oza> +=A0 =A0 =A0 || (1 =3D=3D arm_insn_r->opcode) || (3 =3D=3D arm_insn_= r->opcode) > Oza> +=A0 =A0 =A0 || (5 =3D=3D arm_insn_r->opcode) || (7 =3D=3D arm_insn_= r->opcode)) > > This reads very oddly.=A0 Is there a particular reason behind the ordering > (if so -- document).=A0 If not, isn't > this: > > =A0 if (arm_insn_r->opcode >=3D 0 && arm_insn_r->opcode <=3D 15) > > There are other odd-looking conditions like this. > > Oza> +=A0 =A0 =A0 =A0 =A0 =A0 =A0 default: > Oza> +=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gdb_assert_not_reached ("Invalid ad= dressing mode for insn"); > > Again, assert seems wrong. > > I'm afraid I ran out of steam here.=A0 Please fix all the issues already > noted and look at the rest of the patch with a critical eye to see what > else should be cleaned up.=A0 I want this patch to go in, but first it > must comply to the usual gdb standards. > > Tom >