From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30953 invoked by alias); 27 Sep 2011 03:52:08 -0000 Received: (qmail 30928 invoked by uid 22791); 27 Sep 2011 03:51:59 -0000 X-SWARE-Spam-Status: No, hits=-1.6 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; Tue, 27 Sep 2011 03:51:36 +0000 Received: by wyf22 with SMTP id 22so6934241wyf.0 for ; Mon, 26 Sep 2011 20:51:34 -0700 (PDT) MIME-Version: 1.0 Received: by 10.227.167.1 with SMTP id o1mr8219035wby.6.1317095494211; Mon, 26 Sep 2011 20:51:34 -0700 (PDT) Received: by 10.180.94.234 with HTTP; Mon, 26 Sep 2011 20:51:34 -0700 (PDT) In-Reply-To: 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: Tue, 27 Sep 2011 06:52: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?= 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/msg00454.txt.bz2 Hi Tom, What do you think about the patch to be ready to to move in ? Any more comments are welcome from ARM specific community here. most of the review comments from Michael, Petr, Tom and other folks have been implemented. Regards, Oza. On Thu, Sep 22, 2011 at 7:38 PM, oza Pawandeep wr= ote: > 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 cas= es to arm reversible. >> please find the latest version of the patch after fixing couple of bugs = and 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 +05= 30 >> +++ 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_fr= ame); >> =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 debug= ging 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)*L= ENGTH); \ >> +=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 ar= m_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 b= locks (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 i= nsn being decoded.=A0 */ >> +=A0 uint32_t arm_insn;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Should accom= modate 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 opc= ode.=A0 */ >> +=A0 uint32_t decode;=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 /* Insn dec= ode 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 b= e saved for this record.=A0 */ >> +=A0 struct arm_mem_r *arm_mems;=A0=A0 /* Memory to be saved for this re= cord.=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 l= ater 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, 2= 0)) >> + >> { >> +=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->ar= m_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 instruc= tion 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 = 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 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 padd= ress (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_= addr =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->op= code)) >> +=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 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 /* Handle MLA and MUL.=A0 */ >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[0] =3D bits (arm_insn_r->a= rm_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 a= rm_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_= insn, 16, 19); >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 record_buf[1] =3D bits (arm_insn_r->arm_= insn, 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 = arm_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 precc= edded 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 em= ulates 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 a= nd 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->a= rm_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->o= pcode)) >> +=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 n= ot 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, bit= p[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 st= ores 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 disa= bling normal >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 interrupts, entering abort m= ode.=A0 */ >> +=A0=A0=A0=A0=A0 /* Accorindly to high vector configuration PC is set ac= cordingly */ >> +=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 bac= k 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 i= nstruction " >> +=A0=A0=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 p= address (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 mod= es for store insns >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 STRH insn, addresing modes are taken fol= lowing.=A0 */ >> +=A0=A0=A0 if ((14 =3D=3D arm_insn_r->opcode) || (10 =3D=3D arm_insn_r->= opcode)) >> +=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 curre= nt 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_re= gval + 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_re= gval - 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 curre= nt 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, reg= ister 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_re= gval + 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_re= gval - 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_ins= n_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, reg= ister offset.=A0 */ >> +=A0=A0=A0=A0=A0=A0=A0 if ((15 =3D=3D arm_insn_r->opcode) || (6 =3D=3D a= rm_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_re= gval + 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_re= gval - 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, reg= ister offset.=A0 */ >> +=A0=A0=A0=A0=A0=A0=A0 if ((13 =3D=3D arm_insn_r->opcode) || (4 =3D=3D a= rm_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_re= gval + 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_re= gval - 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] o= f 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 modifi= es destination >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register, which is specif= ied 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_= buf); >> +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_= buf_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 modifi= es destination >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 register, which is specif= ied 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_= buf); >> +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_= buf_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 = insn having Rn as R15 >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 in that case, it emulates branc= h 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 wel= l.=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_ins= n, 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 + of= fset_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 - offse= t_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_ins= n_r->opcode) >> +=A0=A0=A0=A0=A0 || (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_ins= n_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-i= ndexed >> 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_= buf); >> +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_= buf_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_me= m_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 st= ore 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 = insn having Rn as R15 >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 in that case, it emulates branc= h 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 wel= l.=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_ins= n, 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 r= egister 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_= 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].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 reac= h 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 +/- R= m, 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].unsig= ned_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].unsig= ned_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; scal= ed 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_= 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].unsigned_regval); >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0 regcache_raw_read_signed (reg_cache, reg_sr= c1 >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=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_= 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 /* 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 inde= x. >> */ >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offset_12 =3D u_buf[0].un= signed_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_bu= f[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 o= ffset_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 o= ffset_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 ar= ithmetic 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_= read_unsigned (reg_cache, >> ARM_PS_REGNUM >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=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_= 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 /* 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].unsig= ned_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].unsig= ned_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_= buf_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_= bits =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_reg= s =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 = we 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->= arm_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_ins= n, 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_ins= n, 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 n= o 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 reg= ister_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_coun= t; >> +=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_coun= t; >> +=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_coun= t; >> +=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_= buf); >> +=A0 MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_= buf_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_= buf); >> + >> +=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 = address %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 (= arm_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 reco= rd >> 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 instructio= 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 "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, rec= ord_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, rec= ord_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_= 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].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 /* = STR (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_reg= val+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, rec= ord_buf); >> +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, rec= ord_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, rec= ord_buf); >> +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, rec= ord_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, rec= ord_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_= count; >> +=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 disa= bling normal >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 interrupts, entering abort m= ode.=A0 */ >> +=A0=A0=A0=A0=A0 /* Accorindly to high vector configuration PC is set ac= cordingly.=A0 */ >> +=A0=A0=A0=A0=A0 /* FIX ME ?=A0 what if user hit breakpoint and type rev= erse, in >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 that case, we need to go bac= k 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 i= nstruction " >> +=A0=A0=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 (= thumb_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, rec= ord_buf); >> +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, rec= ord_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, registe= r_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_= count; >> +=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 reco= rd 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_= record, >> +=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, rec= ord_buf); >> +=A0 MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, rec= ord_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 sav= ed >> +=A0=A0=A0=A0=A0=A0=A0 there.=A0 */ >> + >> +=A0 REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, rec= ord_buf); >> + >> +=A0 return 0; >> +} >> + >> + >> +/* Decode arm/thumb insn depending on condition cods and opcodes; and d= ispatch 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 /* 0= 10.=A0 */ >> +=A0=A0=A0=A0=A0 thumb_handle_ld_st_imm_offset_insn,=A0=A0=A0=A0=A0 /* 0= 11.=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_= size)) >> +=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->= this_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_in= teger (&u_buf.buf[0] >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 , ARM_INSN_SIZE_BYTES , gdbarch_by= te_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_recor= d) >> +=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 fi= eld 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_in= teger (&u_buf.buf[0] >> +=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 , THUMB_INSN_SIZE_BYTES , gdbarch_byte_o= rder >> (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 i= nstruction 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_ar= ch_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_R= EGNUM); >> +=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_recor= d.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 (a= rm_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= _regs[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_recor= d.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.ar= m_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) * (= reg_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 exec= ution state >> Oza> (before entry to >> >> Oza> +decode_insn() ), contains list of to-be-modified registers and mem= ory 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_in= sn_r->opcode) >> Oza> +=A0 =A0 =A0 || (9 =3D=3D arm_insn_r->opcode) || (11 =3D=3D arm_ins= n_r->opcode) >> Oza> +=A0 =A0 =A0 || (13 =3D=3D arm_insn_r->opcode) || (15 =3D=3D arm_in= sn_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 orderi= ng >> (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 a= ddressing 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 >> >