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