[PATCH] arm reversible : <phase_2_complete>

oza Pawandeep oza.pawandeep@gmail.com
Tue Sep 27 06:52:00 GMT 2011


Hi Tom,

What do you think about the patch to be ready to to move in <phase_2> ?
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 <oza.pawandeep@gmail.com> wrote:
> 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 <paawan1982@yahoo.com> wrote:
>>
>>
>> Hi all,
>>
>> Sorry for delay in fixing review comments.
>>
>> Thanks Chandra for doing testing and working on porintg x86 tcl test cases 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    2011-07-28 09:40:19.000000000 +0530
>> +++ arm_new/arm-linux-tdep.c    2011-07-28 09:41:06.000000000 +0530
>> @@ -1025,6 +1025,9 @@
>>    set_gdbarch_fetch_tls_load_module_address
>> (gdbarch,
>>                                               svr4_fetch_objfile_link_map);
>>
>> +  /* Enable process record.  */
>> +  set_gdbarch_process_record (gdbarch, arm_process_record);
>> +
>>    tramp_frame_prepend_unwinder (gdbarch,
>>                  &arm_linux_sigreturn_tramp_frame);
>>    tramp_frame_prepend_unwinder (gdbarch,
>> @@ -1054,6 +1057,8 @@
>>
>>
>>    tdep->syscall_next_pc = arm_linux_syscall_next_pc;
>> +
>> +  tdep->arm_swi_record = NULL;
>>  }
>>
>>  /* Provide a prototype to silence -Wmissing-prototypes.  */
>> diff -urN
>> arm_orig/arm-tdep.c arm_new/arm-tdep.c
>> --- arm_orig/arm-tdep.c    2011-07-28 09:40:19.000000000 +0530
>> +++ arm_new/arm-tdep.c    2011-09-18 12:55:12.000000000 +0530
>> @@ -55,6 +55,8 @@
>>  #include "gdb_assert.h"
>>  #include "vec.h"
>>
>> +#include "record.h"
>> +
>>  #include "features/arm-with-m.c"
>>
>>  static int arm_debug;
>> @@ -8821,3 +8823,1769 @@
>>                 NULL, /* FIXME: i18n: "ARM debugging is %s.  */
>>                 &setdebuglist, &showdebuglist);
>>  }
>> +/* ARM-reversible process record data structures.  */
>> +
>> +#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  \
>> +  { \
>> +    unsigned int reg_len = LENGTH; \
>> +    if (reg_len) \
>> +      { \
>> +        REGS = XNEWVEC (uint32_t, reg_len); \
>> +        memcpy(&REGS[0],&RECORD_BUF[0],sizeof(uint32_t)*LENGTH); \
>> +      } \
>> +  } \
>> +while (0)
>> +
>> +#define MEM_ALLOC(MEMS,LENGTH,RECORD_BUF) \
>> +do  \
>> +  { \
>> +    unsigned int mem_len = LENGTH; \
>> +    if (mem_len) \
>> +      { \
>> +        MEMS =  XNEWVEC (struct arm_mem_r, mem_len);  \
>> +        memcpy(&MEMS->len,&RECORD_BUF[0],sizeof(struct arm_mem_r) * LENGTH); \
>> +      } \
>> +  }
>> \
>> +while (0)
>> +
>> +
>> +/* ARM memory record structure.  */
>> +struct arm_mem_r
>> +{
>> +  uint32_t len;     /* Record length.  */
>> +  CORE_ADDR addr;   /* Memory address.  */
>> +};
>> +
>> +/* 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() ).  */
>> +typedef struct insn_decode_record_t
>> +{
>> +  struct gdbarch *gdbarch;
>> +  struct regcache *regcache;
>> +  CORE_ADDR this_addr;          /* Address of the insn being decoded.  */
>> +  uint32_t arm_insn;            /* Should accommodate thumb.  */
>> +  uint32_t
>> cond;                /* Condition code.  */
>> +  uint32_t opcode;              /* Insn opcode.  */
>> +  uint32_t decode;              /* Insn decode bits.  */
>> +  uint32_t mem_rec_count;       /* No of mem records */
>> +  uint32_t reg_rec_count;       /* No of reg records */
>> +  uint32_t *arm_regs;           /* Registers to be saved for this record.  */
>> +  struct arm_mem_r *arm_mems;   /* Memory to be saved for this record.  */
>> +} insn_decode_record;
>> +
>> +
>> +/* Checks ARM SBZ and SBO mandatory fields.  */
>> +
>> +static int
>> +sbo_sbz (uint32_t insn,
>> uint32_t bit_num, uint32_t len, uint32_t sbo)
>> +{
>> +  uint32_t ones = bits (insn, bit_num - 1, (bit_num -1) + (len - 1));
>> +
>> +  if (!len)
>> +    return 1;
>> +
>> +  if (!sbo)
>> +    ones = ~ones;
>> +
>> +  while (ones)
>> +    {
>> +      if (!(ones & sbo))
>> +        {
>> +          return 0;
>> +        }
>> +      ones = ones >> 1;
>> +    }
>> +  return 1;
>> +}
>> +
>> +/* Handling ARM extension space insns.  */
>> +
>> +static int
>> +handle_extension_space (insn_decode_record *arm_insn_r)
>> +{
>> +  uint32_t ret = 0;
>> +  uint32_t opcode1 = 0, opcode2 = 0;
>> +
>> +  opcode1 = bits
>> (arm_insn_r->arm_insn, 25, 27);
>> +  if (3 == opcode1 && bit (arm_insn_r->arm_insn, 4))
>> +    {
>> +      ret = -1;
>> +      /* Undefined instruction on ARM V5; need to handle if later versions
>> +          define it.  */
>> +    }
>> +
>> +  opcode2 = bits (arm_insn_r->arm_insn, 4, 7);
>> +
>> +  if (!opcode1 && (9 == opcode2))
>> +    {
>> +      ret = -1;
>> +      /* Handle arithmetic insn extension space.  */
>> +    }
>> +
>> +  opcode1 = bits (arm_insn_r->arm_insn, 26, 27);
>> +  opcode2 = bits (arm_insn_r->arm_insn, 23, 24);
>> +
>> +  if (!opcode1 && (2 == opcode2) && !bit (arm_insn_r->arm_insn, 20))
>> +
>> {
>> +      ret = -1;
>> +      /* Handle control insn extension space.  */
>> +    }
>> +
>> +  opcode1 = bits (arm_insn_r->arm_insn, 25, 27);
>> +  if (!opcode1 && bit (arm_insn_r->arm_insn, 7) \
>> +                 && bit (arm_insn_r->arm_insn, 4))
>> +    {
>> +      ret = -1;
>> +      /* Handle load/store insn extension space.  */
>> +    }
>> +
>> +  opcode1 = bits (arm_insn_r->arm_insn, 23, 27);
>> +  if ((24 == opcode1) && bit (arm_insn_r->arm_insn, 21))
>> +    {
>> +      ret = -1;
>> +      /* Handle coprocessor insn extension space.  */
>> +    }
>> +
>> +  /* To
>> be done for ARMv5 and later; as of now we return -1.  */
>> +  if (-1 == ret)
>> +    printf_unfiltered (_("Process record does not support instruction 0x%0x "
>> +                       "at address %s.\n"),
>> +                       arm_insn_r->arm_insn,
>> +                       paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> +  return ret;
>> +}
>> +
>> +/* Handling opcode 000 insns.  */
>> +
>> +static int
>> +arm_handle_data_proc_misc_ld_str_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  struct regcache *reg_cache = arm_insn_r->regcache;
>> +  uint32_t
>> record_buf[8], record_buf_mem[8];
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf[2];
>> +
>> +
>> +  uint32_t reg_src1 = 0, reg_src2 = 0, reg_dest = 0;
>> +  uint32_t immed_high = 0, immed_low = 0,offset_8 = 0, tgt_mem_addr = 0;
>> +  uint32_t opcode1 = 0;
>> +
>> +  memset (&u_buf, 0, sizeof (u_buf));
>> +
>> +  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
>> +  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);
>> +  opcode1 = bits (arm_insn_r->arm_insn, 20, 24);
>> +
>> +  /* Data processing insn /multiply insn.  */
>> +  if ((9 == arm_insn_r->decode)
>> +     && (((4 <= arm_insn_r->opcode) && (7 >= arm_insn_r->opcode))
>> +     ||  ((0 == arm_insn_r->opcode) || (1 ==
>> arm_insn_r->opcode))))
>> +    {
>> +      /* Handle multiply instructions.  */
>> +      /* MLA, MUL, SMLAL, SMULL, UMLAL, UMULL.  */
>> +        if ((0 == arm_insn_r->opcode) || (1 == arm_insn_r->opcode))
>> +          {
>> +            /* Handle MLA and MUL.  */
>> +            record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
>> +            record_buf[1] = ARM_PS_REGNUM;
>> +            arm_insn_r->reg_rec_count = 2;
>> +
>> }
>> +        else if ((4 <= arm_insn_r->opcode) && (7 >= arm_insn_r->opcode))
>> +         {
>> +          /* Handle SMLAL, SMULL, UMLAL, UMULL.  */
>> +           record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
>> +           record_buf[1] = bits (arm_insn_r->arm_insn, 12, 15);
>> +           record_buf[2] = ARM_PS_REGNUM;
>> +           arm_insn_r->reg_rec_count = 3;
>> +         }
>> +      }
>> +  else if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)
>> +        && ((11 == arm_insn_r->decode) || (13 == arm_insn_r->decode)))
>> +      {
>> +        /* Handle misc load insns, as 20th bit  (L = 1).  */
>> +        /* LDR insn has a capability to do branching, if
>> +                  MOV LR, PC is preccedded by LDR insn having Rn as R15
>> +                  in that case, it emulates branch and link insn, and hence we
>> +                  need to save CSPR and PC as well. I am not sure this is right
>> +                  place as opcode = 010 LDR insn make this happen, if R15 was
>> +                  used.  */
>> +        reg_dest = bits (arm_insn_r->arm_insn, 12, 15);
>> +        if (15 != reg_dest)
>> +          {
>> +            record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +            arm_insn_r->reg_rec_count = 1;
>> +          }
>> +        else
>> +
>> {
>> +            record_buf[0] = reg_dest;
>> +            record_buf[1] = ARM_PS_REGNUM;
>> +            arm_insn_r->reg_rec_count = 2;
>> +          }
>> +      }
>> +  else if (((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode))
>> +      && sbo_sbz (arm_insn_r->arm_insn, 5, 12, 0)
>> +      && sbo_sbz (arm_insn_r->arm_insn, 13, 4, 1)
>> +      && 2 == bits (arm_insn_r->arm_insn, 20, 21))
>> +    {
>> +      /* Handle MSR insn.  */
>> +      if (9 == arm_insn_r->opcode)
>> +
>> {
>> +          /* CSPR is going to be changed.  */
>> +          record_buf[0] = ARM_PS_REGNUM;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +      else
>> +        {
>> +          /* SPSR is going to be changed. */
>> +          /* How to read SPSR value ?  */
>> +          printf_unfiltered (_("Process record does not support instruction "
>> +                             "0x%0x at address
>> %s.\n"),
>> +                             arm_insn_r->arm_insn,
>> +                         paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> +          return -1;
>> +        }
>> +    }
>> +  else if ((9 == arm_insn_r->decode)
>> +           && ((8 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode))
>> +           && !bit (arm_insn_r->arm_insn,  INSN_S_L_BIT_NUM))
>> +    {
>> +      /*
>> Handling SWP, SWPB.  */
>> +      /* These insns, changes register and memory as well.  */
>> +      /* SWP or SWPB insn.  */
>> +      /* Get memory address given by Rn.  */
>> +      reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> +      regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                  , &u_buf[0].unsigned_regval);
>> +      /* SWP insn ?, swaps word.  */
>> +      if (8 == arm_insn_r->opcode)
>> +        {
>> +          record_buf_mem[0] =
>> 4;
>> +        }
>> +        else
>> +        {
>> +          /* SWPB insn, swaps only byte.  */
>> +          record_buf_mem[0] = 1;
>> +        }
>> +      record_buf_mem[1] = u_buf[0].unsigned_regval;
>> +      arm_insn_r->mem_rec_count = 1;
>> +      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +      arm_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if ((3 == arm_insn_r->decode) && (0x12 == opcode1)
>> +           && sbo_sbz (arm_insn_r->arm_insn, 9, 12,
>> 1))
>> +    {
>> +      /* Handle BLX, branch and link/exchange.  */
>> +      if (9 == arm_insn_r->opcode)
>> +      {
>> +        /* Branch is chosen by setting T bit of CSPR, bitp[0] of Rm,
>> +                     and R14 stores the return address.  */
>> +        record_buf[0] = ARM_PS_REGNUM;
>> +        record_buf[1] = ARM_LR_REGNUM;
>> +        arm_insn_r->reg_rec_count = 2;
>> +      }
>> +    }
>> +  else if ((7 == arm_insn_r->decode) && (0x12 == opcode1))
>> +    {
>> +      /* Handle enhanced software
>> breakpoint insn, BKPT */
>> +      /* CPSR is changed to be executed in ARM state,  disabling normal
>> +               interrupts, entering abort mode.  */
>> +      /* Accorindly to high vector configuration PC is set accordingly */
>> +      /* What if user hit breakpoint and type reverse, in
>> +               that case, we need to go back with previous CPSR and
>> +               Program Counter.  */
>> +      record_buf[0] = ARM_PS_REGNUM;
>> +      record_buf[1] = ARM_LR_REGNUM;
>> +      arm_insn_r->reg_rec_count = 2;
>> +
>> +      /* Save SPSR also; how?  */
>> +      printf_unfiltered (_("Process record does not support instruction "
>> +                           "0x%0x at address %s.\n"),
>> +                           arm_insn_r->arm_insn,
>> +                        paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> +      return -1;
>> +    }
>> +  else if ((11 == arm_insn_r->decode)
>> +          && !bit
>> (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> +  {
>> +    /* Handle enhanced store insns and DSP insns (e.g. LDRD)
>> +           let us begin according to addressing modes for store insns
>> +           STRH insn, addresing modes are taken following.  */
>> +    if ((14 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode))
>> +      {
>> +        /* 1) Handle misc store, immediate offset.  */
>> +        immed_low = bits (arm_insn_r->arm_insn, 0, 3);
>> +        immed_high = bits (arm_insn_r->arm_insn, 8, 11);
>> +        reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> +
>> regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                    , &u_buf[0].unsigned_regval);
>> +        if (15 == reg_src1)
>> +          {
>> +            /* If R15 was used as Rn, hence current PC+8.  */
>> +            u_buf[0].unsigned_regval = u_buf[0].unsigned_regval + 8;
>> +          }
>> +        offset_8 = (immed_high << 4) |
>> immed_low;
>> +        /* Calculate target store address.  */
>> +        if (14 == arm_insn_r->opcode)
>> +          {
>> +            tgt_mem_addr = u_buf[0].unsigned_regval + offset_8;
>> +          }
>> +        else
>> +          {
>> +            tgt_mem_addr = u_buf[0].unsigned_regval - offset_8;
>> +          }
>> +        record_buf_mem[0] = 2;
>> +        record_buf_mem[1] = tgt_mem_addr;
>> +        arm_insn_r->mem_rec_count =
>> 1;
>> +      }
>> +    else if ((12 == arm_insn_r->opcode) || (8 == arm_insn_r->opcode))
>> +      {
>> +        /* 2) Store, register offset.  */
>> +        /* Get Rm.  */
>> +        reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
>> +        /* Get Rn.  */
>> +        reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
>> +        regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                    ,
>> &u_buf[0].unsigned_regval);
>> +        regcache_raw_read_unsigned (reg_cache, reg_src2
>> +                                    , &u_buf[1].unsigned_regval);
>> +        if (15 == reg_src2)
>> +          {
>> +            /* If R15 was used as Rn, hence current PC+8.  */
>> +            u_buf[0].unsigned_regval = u_buf[0].unsigned_regval + 8;
>> +
>> }
>> +        /* Calculate target store address, Rn +/- Rm, register offset.  */
>> +        if (12 == arm_insn_r->opcode)
>> +          {
>> +            tgt_mem_addr = u_buf[0].unsigned_regval + u_buf[1].unsigned_regval;
>> +          }
>> +        else
>> +          {
>> +            tgt_mem_addr = u_buf[1].unsigned_regval - u_buf[0].unsigned_regval;
>> +          }
>> +
>> record_buf_mem[0] = 2;
>> +        record_buf_mem[1] = tgt_mem_addr;
>> +        arm_insn_r->mem_rec_count = 1;
>> +      }
>> +    else if ((11 == arm_insn_r->opcode) || (15 == arm_insn_r->opcode)
>> +      || (2 == arm_insn_r->opcode) || (6 == arm_insn_r->opcode))
>> +      {
>> +        /* 3) Store, immediate pre-indexed.  */
>> +        /* 5) Store, immediate post-indexed.  */
>> +        immed_low = bits (arm_insn_r->arm_insn, 0, 3);
>> +        immed_high = bits (arm_insn_r->arm_insn, 8, 11);
>> +        offset_8 =
>> (immed_high << 4) | immed_low;
>> +        reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> +        regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                   , &u_buf[0].unsigned_regval);
>> +        /* Calculate target store address, Rn +/- Rm, register offset.  */
>> +        if ((15 == arm_insn_r->opcode) || (6 == arm_insn_r->opcode))
>> +          {
>> +            tgt_mem_addr = u_buf[0].unsigned_regval + offset_8;
>> +
>> }
>> +        else
>> +          {
>> +            tgt_mem_addr = u_buf[0].unsigned_regval - offset_8;
>> +          }
>> +        record_buf_mem[0] = 2;
>> +        record_buf_mem[1] = tgt_mem_addr;
>> +        arm_insn_r->mem_rec_count = 1;
>> +        /* Record Rn also as it changes.  */
>> +        record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
>> +        arm_insn_r->reg_rec_count = 1;
>> +      }
>> +    else if ((9 ==
>> arm_insn_r->opcode) || (13 == arm_insn_r->opcode)
>> +      || (0 == arm_insn_r->opcode) || (4 == arm_insn_r->opcode))
>> +      {
>> +        /* 4) Store, register pre-indexed.  */
>> +        /* 6) Store, register post -indexed.  */
>> +        reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
>> +        reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
>> +        regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                    ,
>> &u_buf[0].unsigned_regval);
>> +        regcache_raw_read_unsigned (reg_cache, reg_src2
>> +                                    , &u_buf[1].unsigned_regval);
>> +        /* Calculate target store address, Rn +/- Rm, register offset.  */
>> +        if ((13 == arm_insn_r->opcode) || (4 == arm_insn_r->opcode))
>> +          {
>> +            tgt_mem_addr = u_buf[0].unsigned_regval + u_buf[1].unsigned_regval;
>> +          }
>> +
>> else
>> +          {
>> +            tgt_mem_addr = u_buf[1].unsigned_regval - u_buf[0].unsigned_regval;
>> +          }
>> +        record_buf_mem[0] = 2;
>> +        record_buf_mem[1] = tgt_mem_addr;
>> +        arm_insn_r->mem_rec_count = 1;
>> +        /* Record Rn also as it changes.  */
>> +        record_buf[0] = bits (arm_insn_r->arm_insn, 16, 19);
>> +        arm_insn_r->reg_rec_count = 1;
>> +
>> }
>> +    /* DSP insns  (e.g. LDRD)  TBD.  */
>> +  }
>> +  else if ((1 == arm_insn_r->decode) && (0x12 == opcode1)
>> +           && sbo_sbz (arm_insn_r->arm_insn, 9, 12, 1))
>> +    {
>> +      /* Handle BX, branch and link/exchange.  */
>> +      /* Branch is chosen by setting T bit of CSPR, bitp[0] of Rm.  */
>> +      record_buf[0] = ARM_PS_REGNUM;
>> +      arm_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if ((1 == arm_insn_r->decode) && (0x16 == opcode1)
>> +           && sbo_sbz (arm_insn_r->arm_insn, 9, 4, 1)
>> +           && sbo_sbz
>> (arm_insn_r->arm_insn, 17, 4, 1))
>> +    {
>> +      /* Count leading zeros: CLZ.  */
>> +      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +      arm_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (!bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM)
>> +          && ((8 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode))
>> +          && sbo_sbz (arm_insn_r->arm_insn, 17, 4, 1)
>> +          && sbo_sbz (arm_insn_r->arm_insn, 1, 12, 0)
>> +          )
>> +    {
>> +      /* Handle MRS insn.  */
>> +
>> record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +      arm_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (arm_insn_r->opcode <= 15)
>> +    {
>> +      /* Normal data processing insns.  */
>> +      /* Out of 11 shifter operands mode, all the insn modifies destination
>> +                register, which is specified by 13-16 decode.  */
>> +      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +      record_buf[1] = ARM_PS_REGNUM;
>> +      arm_insn_r->reg_rec_count = 2;
>> +    }
>> +  else
>> +
>> {
>> +      return -1;
>> +    }
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 001 insns.  */
>> +
>> +static int
>> +arm_handle_data_proc_imm_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  uint32_t record_buf[8], record_buf_mem[8];
>> +
>> +  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
>> +  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);
>> +
>> +  if (((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode))
>> +       && (2 == bits (arm_insn_r->arm_insn, 20, 21))
>> +       && sbo_sbz (arm_insn_r->arm_insn, 13, 4, 1)
>> +
>> )
>> +    {
>> +      /* Handle MSR insn.  */
>> +      if (9 == arm_insn_r->opcode)
>> +        {
>> +          /*CSPR is going to be changed.  */
>> +          record_buf[0] = ARM_PS_REGNUM;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +      else
>> +        {
>> +           /* SPSR is going to be changed.  */
>> +        }
>> +    }
>> +  else if (arm_insn_r->opcode <= 15)
>> +    {
>> +      /* Normal data
>> processing insns.  */
>> +      /* Out of 11 shifter operands mode, all the insn modifies destination
>> +                register, which is specified by 13-16 decode.  */
>> +      record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +      record_buf[1] = ARM_PS_REGNUM;
>> +      arm_insn_r->reg_rec_count = 2;
>> +    }
>> +  else
>> +    {
>> +      return -1;
>> +    }
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 010 insns.
>> */
>> +
>> +static int
>> +arm_handle_ld_st_imm_offset_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> +  uint32_t reg_src1 = 0 , reg_dest = 0;
>> +  uint32_t offset_12 = 0, tgt_mem_addr = 0;
>> +  uint32_t record_buf[8], record_buf_mem[8];
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  memset (&u_buf, 0, sizeof (u_buf));
>> +  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
>> +  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);
>> +
>> +  if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> +    {
>> +      reg_dest = bits (arm_insn_r->arm_insn, 12, 15);
>> +      /* LDR insn has a capability to do branching,
>> if
>> +              MOV LR, PC is precedded by LDR insn having Rn as R15
>> +              in that case, it emulates branch and link insn, and hence we
>> +              need to save CSPR and PC as well.  */
>> +      if (15 != reg_dest)
>> +        {
>> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +      else
>> +        {
>> +          record_buf[0] =
>> reg_dest;
>> +          record_buf[1] = ARM_PS_REGNUM;
>> +          arm_insn_r->reg_rec_count = 2;
>> +        }
>> +    }
>> +  else
>> +    {
>> +      /* Store, immediate offset, immediate pre-indexed,
>> +            immediate post-indexed.  */
>> +      reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> +      offset_12 = bits (arm_insn_r->arm_insn, 0, 11);
>> +      regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> +                                  , &u_buf.unsigned_regval);
>> +      /* U == 1 */
>> +      if (bit (arm_insn_r->arm_insn, 23))
>> +        {
>> +          tgt_mem_addr = u_buf.unsigned_regval + offset_12;
>> +        }
>> +      else
>> +        {
>> +         tgt_mem_addr = u_buf.unsigned_regval - offset_12;
>> +        }
>> +
>> +      switch (arm_insn_r->opcode)
>> +
>> {
>> +          /* STR */
>> +          case 8:
>> +          case 12:
>> +           /* STR */
>> +          case 9:
>> +          case 13:
>> +         /* STRT */
>> +          case 1:
>> +          case 5:
>> +         /* STR */
>> +          case 4:
>> +           case 0:
>> +
>> +            /* STR insn, STRT insn.  */
>> +            record_buf_mem[0] = 4;
>> +          break;
>> +
>> +         /* STRB */
>> +          case 10:
>> +          case 14:
>> +         /* STRB */
>> +          case 11:
>> +          case 15:
>> +         /* STRBT */
>> +          case 3:
>> +          case
>> 7:
>> +         /* STRB */
>> +         case 2:
>> +         case 6:
>> +            /* STRB insn, STRBT insn.  */
>> +            record_buf_mem[0] = 1;
>> +          break;
>> +
>> +          default:
>> +            return -1;
>> +          break;
>> +        }
>> +      record_buf_mem[1] = tgt_mem_addr;
>> +
>> arm_insn_r->mem_rec_count = 1;
>> +
>> +      if ((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode)
>> +      || (13 == arm_insn_r->opcode) || (15 == arm_insn_r->opcode)
>> +      || (0 == arm_insn_r->opcode) || (2 == arm_insn_r->opcode)
>> +      || (4 == arm_insn_r->opcode) || (6 == arm_insn_r->opcode)
>> +      || (1 == arm_insn_r->opcode) || (3 == arm_insn_r->opcode)
>> +      || (5 == arm_insn_r->opcode) || (7 == arm_insn_r->opcode))
>> +        {
>> +          /* We are handling pre-indexed mode; post-indexed
>> mode;
>> +                         where Rn is going to be changed.  */
>> +          record_buf[0] = reg_src1;
>> +          arm_insn_r->reg_rec_count = 1;
>> +        }
>> +    }
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 011 insns.  */
>> +
>> +static int
>> +arm_handle_ld_st_reg_offset_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> +  uint32_t shift_imm = 0;
>> +  uint32_t
>> reg_src1 = 0, reg_src2 = 0, reg_dest = 0;
>> +  uint32_t immed_high = 0, immed_low = 0, offset_12 = 0, tgt_mem_addr = 0;
>> +  uint32_t record_buf[8], record_buf_mem[8];
>> +
>> +  struct
>> +    {
>> +      LONGEST signed_word;
>> +      ULONGEST unsigned_regval;
>> +    } u_buf[2];
>> +
>> +  memset (&u_buf, 0, sizeof (u_buf));
>> +  arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 21, 24);
>> +  arm_insn_r->decode = bits (arm_insn_r->arm_insn, 4, 7);
>> +
>> +  /* Handle enhanced store insns and LDRD DSP insn,
>> +        let us begin according to addressing modes for store insns
>> +        STRH insn.  */
>> +
>> +  /* LDR or STR?  */
>> +  if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> +
>> {
>> +      reg_dest = bits (arm_insn_r->arm_insn, 12, 15);
>> +      /* LDR insn has a capability to do branching, if
>> +              MOV LR, PC is precedded by LDR insn having Rn as R15
>> +              in that case, it emulates branch and link insn, and hence we
>> +              need to save CSPR and PC as well.  */
>> +      if (15 != reg_dest)
>> +        {
>> +          record_buf[0] = bits (arm_insn_r->arm_insn, 12, 15);
>> +          arm_insn_r->reg_rec_count = 1;
>> +
>> }
>> +      else
>> +        {
>> +          record_buf[0] = reg_dest;
>> +          record_buf[1] = ARM_PS_REGNUM;
>> +          arm_insn_r->reg_rec_count = 2;
>> +        }
>> +    }
>> +  else
>> +    {
>> +      if (! bits (arm_insn_r->arm_insn, 4, 11))
>> +        {
>> +          /* Store insn, register offset and register pre-indexed,
>> +                        register post-indexed.  */
>> +          /* Get
>> Rm.  */
>> +          reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
>> +          /* Get Rn.  */
>> +          reg_src2 = bits (arm_insn_r->arm_insn, 16, 19);
>> +          regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                      , &u_buf[0].unsigned_regval);
>> +          regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> +                                      , &u_buf[1].unsigned_regval);
>> +          if (15 == reg_src2)
>> +            {
>> +              /* If R15 was used as Rn, hence current PC+8.  */
>> +              /* Pre-indexed mode doesnt reach here ; illegal insn.  */
>> +              u_buf[0].unsigned_regval =
>> u_buf[0].unsigned_regval + 8;
>> +            }
>> +          /* Calculate target store address, Rn +/- Rm, register offset.  */
>> +          /* U == 1.  */
>> +          if (bit (arm_insn_r->arm_insn, 23))
>> +            {
>> +              tgt_mem_addr = u_buf[0].unsigned_regval +
>> +                             u_buf[1].unsigned_regval;
>> +
>> }
>> +          else
>> +            {
>> +              tgt_mem_addr = u_buf[1].unsigned_regval -
>> +                             u_buf[0].unsigned_regval;
>> +            }
>> +
>> +          switch (arm_insn_r->opcode)
>> +            {
>> +              /* STR */
>> +              case
>> 8:
>> +              case 12:
>> +          /* STR */
>> +              case 9:
>> +              case 13:
>> +          /* STRT */
>> +              case 1:
>> +              case 5:
>> +          /* STR */
>> +          case 0:
>> +          case
>> 4:
>> +                /* STR insn, STRT insn.  */
>> +                record_buf_mem[0] = 4;
>> +              break;
>> +
>> +              /* STRB */
>> +              case 10:
>> +              case 14:
>> +          /* STRB */
>> +              case 11:
>> +              case 15:
>> +          /* STRBT */
>> +              case 3:
>> +              case 7:
>> +               /* STRB */
>> +          case 2:
>> +          case 6:
>> +                /* STRB insn, STRBT insn.  */
>> +                record_buf_mem[0] = 1;
>> +              break;
>> +
>> +
>> default:
>> +                return -1;
>> +              break;
>> +            }
>> +          record_buf_mem[1] = tgt_mem_addr;
>> +          arm_insn_r->mem_rec_count = 1;
>> +
>> +          if ((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode)
>> +          || (13 == arm_insn_r->opcode) || (15 == arm_insn_r->opcode)
>> +          || (0 == arm_insn_r->opcode) || (2 == arm_insn_r->opcode)
>> +          || (4 == arm_insn_r->opcode) || (6 == arm_insn_r->opcode)
>> +          || (1 == arm_insn_r->opcode) || (3 == arm_insn_r->opcode)
>> +          || (5 == arm_insn_r->opcode) || (7 == arm_insn_r->opcode))
>> +            {
>> +              /* Rn is going to be changed in pre-indexed mode and
>> +                              post-indexed mode as well.  */
>> +              record_buf[0] = reg_src2;
>> +              arm_insn_r->reg_rec_count = 1;
>> +            }
>> +        }
>> +      else
>> +        {
>> +          /* Store insn, scaled register offset; scaled pre-indexed.  */
>> +          offset_12 = bits (arm_insn_r->arm_insn, 5, 6);
>> +          /* Get Rm.  */
>> +          reg_src1 = bits (arm_insn_r->arm_insn, 0, 3);
>> +          /* Get Rn.  */
>> +          reg_src2 = bits (arm_insn_r->arm_insn, 16,
>> 19);
>> +          /* Get shift_imm.  */
>> +          shift_imm = bits (arm_insn_r->arm_insn, 7, 11);
>> +          regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                      , &u_buf[0].unsigned_regval);
>> +          regcache_raw_read_signed (reg_cache, reg_src1
>> +                                      ,
>> &u_buf[0].signed_word);
>> +          regcache_raw_read_unsigned (reg_cache, reg_src2
>> +                                      , &u_buf[1].unsigned_regval);
>> +          /* Offset_12 used as shift.  */
>> +          switch (offset_12)
>> +            {
>> +              case 0:
>> +                /* Offset_12 used as index.
>> */
>> +                offset_12 = u_buf[0].unsigned_regval << shift_imm;
>> +              break;
>> +
>> +              case 1:
>> +                offset_12 = (!shift_imm)?0:u_buf[0].unsigned_regval >> shift_imm;
>> +              break;
>> +
>> +              case 2:
>> +                if
>> (!shift_imm)
>> +                  {
>> +                    if (bit (u_buf[0].unsigned_regval, 31))
>> +                      {
>> +                        offset_12 = 0xFFFFFFFF;
>> +                      }
>> +
>> else
>> +                      {
>> +                        offset_12 = 0;
>> +                      }
>> +                  }
>> +                else
>> +                  {
>> +                    /* This is arithmetic shift.
>> */
>> +                    offset_12 = u_buf[0].signed_word >> shift_imm;
>> +                  }
>> +                break;
>> +
>> +              case 3:
>> +                if (!shift_imm)
>> +                  {
>> +                    regcache_raw_read_unsigned (reg_cache,
>> ARM_PS_REGNUM
>> +                                                , &u_buf[1].unsigned_regval);
>> +                    /* Get C flag value and shift it by 31.  */
>> +                    offset_12 = (((bit (u_buf[1].unsigned_regval, 29)) << 31) \
>> +                                  | (u_buf[0].unsigned_regval) >>
>> 1);
>> +                  }
>> +                else
>> +                  {
>> +                    offset_12 = (u_buf[0].unsigned_regval >> shift_imm) \
>> +                       | (u_buf[0].unsigned_regval << (sizeof(uint32_t) - shift_imm));
>> +
>> }
>> +              break;
>> +
>> +              default:
>> +                return -1;
>> +              break;
>> +            }
>> +
>> +          regcache_raw_read_unsigned (reg_cache, reg_src2
>> +                                      , &u_buf[1].unsigned_regval);
>> +          /* U == 1
>> */
>> +          if (bit (arm_insn_r->arm_insn, 23))
>> +            {
>> +              tgt_mem_addr = u_buf[1].unsigned_regval + offset_12;
>> +            }
>> +          else
>> +            {
>> +              tgt_mem_addr = u_buf[1].unsigned_regval - offset_12;
>> +            }
>> +
>> +          switch
>> (arm_insn_r->opcode)
>> +            {
>> +              /* STR */
>> +              case 8:
>> +              case 12:
>> +          /* STR */
>> +              case 9:
>> +              case 13:
>> +          /* STRT */
>> +              case 1:
>> +              case
>> 5:
>> +          /* STR */
>> +          case 0:
>> +          case 4:
>> +                /* STR insn, STRT insn.  */
>> +                record_buf_mem[0] = 4;
>> +              break;
>> +
>> +               /* STRB */
>> +              case 10:
>> +              case 14:
>> +
>>       /* STRB */
>> +              case 11:
>> +              case 15:
>> +          /* STRBT */
>> +              case 3:
>> +              case 7:
>> +               /* STRB */
>> +          case 2:
>> +          case 6:
>> +                /* STRB insn, STRBT insn.
>> */
>> +                record_buf_mem[0] = 1;
>> +              break;
>> +
>> +              default:
>> +                return -1;
>> +              break;
>> +            }
>> +          record_buf_mem[1] = tgt_mem_addr;
>> +          arm_insn_r->mem_rec_count =
>> 1;
>> +
>> +          if ((9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode)
>> +          || (13 == arm_insn_r->opcode) || (15 == arm_insn_r->opcode)
>> +          || (0 == arm_insn_r->opcode) || (2 == arm_insn_r->opcode)
>> +          || (4 == arm_insn_r->opcode) || (6 == arm_insn_r->opcode)
>> +          || (1 == arm_insn_r->opcode) || (3 == arm_insn_r->opcode)
>> +          || (5 == arm_insn_r->opcode) || (7 ==
>> arm_insn_r->opcode))
>> +            {
>> +              /* Rn is going to be changed in register scaled pre-indexed
>> +                              mode, and scaled post indexed mode.  */
>> +              record_buf[0] = reg_src2;
>> +              arm_insn_r->reg_rec_count = 1;
>> +            }
>> +        }
>> +    }
>> +
>> +  REG_ALLOC
>> (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 100 insns.  */
>> +
>> +static int
>> +arm_handle_ld_st_multiple_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> +  uint32_t register_list[16] = {0}, register_count = 0, register_bits = 0;
>> +  uint32_t shift_imm = 0;
>> +  uint32_t reg_src1 = 0, reg_src2 = 0, addr_mode = 0, no_of_regs = 0;
>> +  uint32_t start_address = 0, index = 0;
>> +  uint32_t record_buf[24], record_buf_mem[48];
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf[2];
>> +
>> +  memset (&u_buf, 0,
>> sizeof(u_buf));
>> +
>> +  /* This mode is exclusively for load and store multiple.  */
>> +  /* Handle incremenrt after/before and decrment after.before mode;
>> +        Rn is changing depending on W bit, but as of now we store Rn too without optmization.  */
>> +
>> +  if (bit (arm_insn_r->arm_insn, INSN_S_L_BIT_NUM))
>> +    {
>> +      /* LDM  (1,2,3) where LDM  (3) changes CPSR too.  */
>> +
>> +      if (bit (arm_insn_r->arm_insn,20) && !bit (arm_insn_r->arm_insn,22))
>> +        {
>> +          register_bits = bits (arm_insn_r->arm_insn, 0, 15);
>> +          no_of_regs = 15;
>> +        }
>> +
>> else
>> +        {
>> +          register_bits = bits (arm_insn_r->arm_insn, 0, 14);
>> +          no_of_regs = 14;
>> +        }
>> +      /* Get Rn.  */
>> +      reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> +      while (register_bits)
>> +       {
>> +         if (register_bits & 0x00000001)
>> +           register_list[register_count++] = 1;
>> +         register_bits = register_bits >> 1;
>> +       }
>> +
>> +        /* Extra space for
>> Base Register and CPSR; wihtout optmization.  */
>> +        record_buf[register_count] = reg_src1;
>> +        record_buf[register_count + 1] = ARM_PS_REGNUM;
>> +        arm_insn_r->reg_rec_count = register_count + 2;
>> +
>> +        for (register_count = 0; register_count < no_of_regs; register_count++)
>> +          {
>> +            if  (register_list[register_count])
>> +              {
>> +              /* Register_count gives total no of registers and dually working
>> +                             as reg number.  */
>> +                record_buf[index] = register_count;
>> +                index++;
>> +              }
>> +          }
>> +
>> +    }
>> +  else
>> +    {
>> +    /* It handles both STM(1) and STM(2).  */
>> +    addr_mode = bits (arm_insn_r->arm_insn, 23, 24);
>> +
>> +    register_bits = bits (arm_insn_r->arm_insn, 0, 15);
>> +    /*
>> Get Rn.  */
>> +    reg_src1 = bits (arm_insn_r->arm_insn, 16, 19);
>> +    regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                , &u_buf[0].unsigned_regval);
>> +    while (register_bits)
>> +      {
>> +        if (register_bits & 0x00000001)
>> +           register_count++;
>> +        register_bits = register_bits >> 1;
>> +      }
>> +
>> +    switch (addr_mode)
>> +      {
>> +        /* Decrement after.  */
>> +        case 0:
>> +          start_address = (u_buf[0].unsigned_regval) - (register_count * 4) + 4;
>> +          arm_insn_r->mem_rec_count = register_count;
>> +          while (register_count)
>> +            {
>> +              record_buf_mem[(register_count * 2) - 1] = start_address;
>> +              record_buf_mem[(register_count * 2) - 2] = 4;
>> +              start_address = start_address +
>> 4;
>> +              register_count--;
>> +            }
>> +        break;
>> +
>> +        /* Increment after.  */
>> +        case 1:
>> +          start_address = u_buf[0].unsigned_regval;
>> +          arm_insn_r->mem_rec_count = register_count;
>> +          while (register_count)
>> +            {
>> +              record_buf_mem[(register_count * 2) - 1] =
>> start_address;
>> +              record_buf_mem[(register_count * 2) - 2] = 4;
>> +              start_address = start_address + 4;
>> +              register_count--;
>> +            }
>> +        break;
>> +
>> +        /* Decrement before.  */
>> +        case 2:
>> +
>> +          start_address = (u_buf[0].unsigned_regval) - (register_count * 4);
>> +          arm_insn_r->mem_rec_count =
>> register_count;
>> +          while (register_count)
>> +            {
>> +              record_buf_mem[(register_count * 2) - 1] = start_address;
>> +              record_buf_mem[(register_count * 2) - 2] = 4;
>> +              start_address = start_address + 4;
>> +              register_count--;
>> +            }
>> +        break;
>> +
>> +        /* Increment before.  */
>> +        case
>> 3:
>> +          start_address = u_buf[0].unsigned_regval + 4;
>> +          arm_insn_r->mem_rec_count = register_count;
>> +          while (register_count)
>> +            {
>> +              record_buf_mem[(register_count * 2) - 1] = start_address;
>> +              record_buf_mem[(register_count * 2) - 2] = 4;
>> +              start_address = start_address + 4;
>> +
>> register_count--;
>> +            }
>> +        break;
>> +
>> +        default:
>> +          return -1;
>> +        break;
>> +      }
>> +
>> +    /* Base register also changes; based on condition and W bit.  */
>> +    /* We save it anyway without optimization.  */
>> +    record_buf[0] = reg_src1;
>> +    arm_insn_r->reg_rec_count = 1;
>> +    }
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (arm_insn_r->arm_mems, arm_insn_r->mem_rec_count, record_buf_mem);
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode
>> 101 insns.  */
>> +
>> +static int
>> +arm_handle_brn_insn (insn_decode_record *arm_insn_r)
>> +{
>> +
>> +  uint32_t record_buf[8];
>> +
>> +  /* Handle B, BL, BLX(1) insns.  */
>> +  /* Wihtout optmization we save link register,
>> +        CSPR for the insn which changes T bit.  */
>> +  record_buf[0] = ARM_PS_REGNUM;
>> +  record_buf[1] = ARM_LR_REGNUM;
>> +  arm_insn_r->reg_rec_count = 2;
>> +
>> +  REG_ALLOC (arm_insn_r->arm_regs, arm_insn_r->reg_rec_count, record_buf);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 110 insns.  */
>> +
>> +static int
>> +arm_handle_coproc_insn (insn_decode_record *arm_insn_r)
>> +{
>> +  printf_unfiltered (_("Process record does not support instruction
>> "
>> +                     "0x%0x at address %s.\n"),
>> +                     arm_insn_r->arm_insn,
>> +                     paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> +
>> +   return -1;
>> +}
>> +
>> +/* Handling opcode 111 insns.  */
>> +
>> +static int
>> +arm_handle_coproc_data_proc_insn (insn_decode_record *arm_insn_r)
>> +{
>> +   struct gdbarch_tdep *tdep = gdbarch_tdep (arm_insn_r->gdbarch);
>> +   struct regcache *reg_cache = arm_insn_r->regcache;
>> +
>> +   uint32_t shift_imm = 0;
>> +   uint32_t reg_src1 = 0, reg_src2 = 0, addr_mode =
>> 0;
>> +   uint32_t start_address = 0;
>> +
>> +   /* Handle SWI insn; system call would be handled over here.  */
>> +
>> +   arm_insn_r->opcode = bits (arm_insn_r->arm_insn, 24, 27);
>> +   if (15 == arm_insn_r->opcode)
>> +   {
>> +        /* Handle arm syscall insn.  */
>> +        if (tdep->arm_swi_record != NULL)
>> +          {
>> +            tdep->arm_swi_record(reg_cache);
>> +          }
>> +        else
>> +          {
>> +            printf_unfiltered (_("no syscall record
>> support\n"));
>> +            return -1;
>> +          }
>> +   }
>> +
>> +   printf_unfiltered (_("Process record does not support instruction "
>> +                         "0x%0x at address %s.\n"),
>> +                         arm_insn_r->arm_insn,
>> +                         paddress (arm_insn_r->gdbarch, arm_insn_r->this_addr));
>> +   return -1;
>> +}
>> +
>> +/* Handling opcode 000 insns.  */
>> +
>> +static int
>> +thumb_handle_shift_add_sub_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  uint32_t record_buf[8];
>> +  uint32_t reg_src1 = 0;
>> +
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
>> +
>> +  record_buf[0] = ARM_PS_REGNUM;
>> +  record_buf[1] = reg_src1;
>> +  thumb_insn_r->reg_rec_count = 2;
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +
>> +  return 0;
>> +}
>> +
>> +
>> +/* Handling opcode 001 insns.  */
>> +
>> +static int
>> +thumb_handle_add_sub_cmp_mov_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  uint32_t record_buf[8];
>> +  uint32_t reg_src1 = 0;
>> +
>> +  reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +
>> +  record_buf[0] =
>> ARM_PS_REGNUM;
>> +  record_buf[1] = reg_src1;
>> +  thumb_insn_r->reg_rec_count = 2;
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 010 insns.  */
>> +
>> +static int
>> +thumb_handle_ld_st_reg_offset_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  struct regcache *reg_cache =  thumb_insn_r->regcache;
>> +  uint32_t record_buf[8], record_buf_mem[8];
>> +
>> +  uint32_t reg_src1 = 0, reg_src2 = 0;
>> +  uint32_t opcode1 = 0, opcode2 = 0, opcode3 = 0;
>> +
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +      gdb_byte buf[4];
>> +    } u_buf[2];
>> +
>> +  opcode1 = bits (thumb_insn_r->arm_insn, 10, 12);
>> +
>> +  if (bit (thumb_insn_r->arm_insn,
>> 12))
>> +    {
>> +      /* Handle load/store register offset.  */
>> +      opcode2 = bits (thumb_insn_r->arm_insn, 9, 10);
>> +      if ((opcode2 >= 12) && (opcode2 <= 15))
>> +        {
>> +          /* LDR(2), LDRB(2) , LDRH(2), LDRSB, LDRSH.  */
>> +          reg_src1 = bits (thumb_insn_r->arm_insn,0, 2);
>> +          record_buf[0] = reg_src1;
>> +          thumb_insn_r->reg_rec_count = 1;
>> +        }
>> +      else if ((opcode2 >= 8)
>> && (opcode2 <= 10))
>> +        {
>> +          /* STR(2), STRB(2), STRH(2) .  */
>> +          reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
>> +          reg_src2 = bits (thumb_insn_r->arm_insn, 6, 8);
>> +          regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                      , &u_buf[0].unsigned_regval);
>> +          regcache_raw_read_unsigned (reg_cache,
>> reg_src2
>> +                                      , &u_buf[1].unsigned_regval);
>> +          if (8 == opcode2)
>> +            record_buf_mem[0] = 4;    /* STR (2).  */
>> +          else if (10 == opcode2)
>> +            record_buf_mem[0] = 1;    /*  STRB (2).  */
>> +          else if (9 == opcode2)
>> +            record_buf_mem[0] =
>> 2;    /* STRH (2).  */
>> +          record_buf_mem[1] = u_buf[0].unsigned_regval+u_buf[1].unsigned_regval;
>> +          thumb_insn_r->mem_rec_count = 1;
>> +        }
>> +    }
>> +  else if (bit (thumb_insn_r->arm_insn, 11))
>> +    {
>> +      /* Handle load from literal pool.  */
>> +      /* LDR(3).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +      record_buf[0] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (opcode1)
>> +    {
>> +      opcode2 = bits (thumb_insn_r->arm_insn, 8, 9);
>> +      opcode3 = bits (thumb_insn_r->arm_insn, 0, 2);
>> +      if ((3 == opcode2) && (!opcode3))
>> +        {
>> +          /* Branch with exchange.  */
>> +          record_buf[0] = ARM_PS_REGNUM;
>> +          thumb_insn_r->reg_rec_count = 1;
>> +        }
>> +      else
>> +
>> {
>> +          /* Format 8; special data processing insns.  */
>> +          reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
>> +          record_buf[0] = ARM_PS_REGNUM;
>> +          record_buf[1] = reg_src1;
>> +          thumb_insn_r->reg_rec_count = 2;
>> +        }
>> +    }
>> +  else
>> +    {
>> +      /* Format 5; data processing insns.  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
>> +      if (bit (thumb_insn_r->arm_insn, 7))
>> +        {
>> +          reg_src1
>> = reg_src1 + 8;
>> +        }
>> +      record_buf[0] = ARM_PS_REGNUM;
>> +      record_buf[1] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = 2;
>> +    }
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, record_buf_mem);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 001 insns.  */
>> +
>> +static int
>> +thumb_handle_ld_st_imm_offset_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  struct regcache *reg_cache = thumb_insn_r->regcache;
>> +  uint32_t record_buf[8], record_buf_mem[8];
>> +
>> +  uint32_t reg_val1 = 0;
>> +  uint32_t reg_src1 = 0;
>> +  uint32_t opcode = 0, immed_5 = 0;
>> +
>> +
>> struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  opcode = bits (thumb_insn_r->arm_insn, 11, 12);
>> +
>> +  if (opcode)
>> +    {
>> +      /* LDR(1).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 0, 2);
>> +      record_buf[0] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +  else
>> +    {
>> +      /* STR(1).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
>> +      immed_5 = bits (thumb_insn_r->arm_insn, 6, 10);
>> +      regcache_raw_read_unsigned (reg_cache,
>> reg_src1
>> +                                  , &u_buf.unsigned_regval);
>> +      record_buf_mem[0] = 4;
>> +      record_buf_mem[1] = u_buf.unsigned_regval + (immed_5 * 4);
>> +      thumb_insn_r->mem_rec_count = 1;
>> +    }
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, record_buf_mem);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 100 insns.  */
>> +
>> +static int
>> +thumb_handle_ld_st_stack_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  struct regcache *reg_cache = thumb_insn_r->regcache;
>> +  uint32_t
>> record_buf[8], record_buf_mem[8];
>> +
>> +  uint32_t reg_val1 = 0;
>> +  uint32_t reg_src1 = 0;
>> +  uint32_t opcode = 0, immed_8 = 0, immed_5 = 0;
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  opcode = bits (thumb_insn_r->arm_insn, 11, 12);
>> +
>> +  if (3 == opcode)
>> +    {
>> +      /* LDR(4).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +      record_buf[0] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (1 == opcode)
>> +    {
>> +      /* LDRH(1).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 0,
>> 2);
>> +      record_buf[0] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (2 == opcode)
>> +    {
>> +      /* STR(3).  */
>> +      immed_8 = bits (thumb_insn_r->arm_insn, 0, 7);
>> +      regcache_raw_read_unsigned (reg_cache, ARM_SP_REGNUM
>> +                                  , &u_buf.unsigned_regval);
>> +      record_buf_mem[0] = 4;
>> +      record_buf_mem[1] = u_buf.unsigned_regval + (immed_8 * 4);
>> +      thumb_insn_r->mem_rec_count = 1;
>> +    }
>> +  else if (0 ==
>> opcode)
>> +    {
>> +      /* STRH(1).  */
>> +      immed_5 = bits (thumb_insn_r->arm_insn, 6, 10);
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 3, 5);
>> +      regcache_raw_read_unsigned (reg_cache, reg_src1
>> +                                  , &u_buf.unsigned_regval);
>> +      record_buf_mem[0] = 2;
>> +      record_buf_mem[1] = u_buf.unsigned_regval + (immed_5 * 2);
>> +      thumb_insn_r->mem_rec_count = 1;
>> +    }
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC
>> (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, record_buf_mem);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 101 insns.  */
>> +
>> +static int
>> +thumb_handle_misc_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  struct regcache *reg_cache = thumb_insn_r->regcache;
>> +
>> +  uint32_t reg_val1 = 0;
>> +  uint32_t reg_src1 = 0;
>> +  uint32_t opcode = 0, opcode1 = 0, opcode2 = 0, immed_8 = 0, immed_5 = 0;
>> +  uint32_t register_bits = 0, register_count = 0;
>> +  uint32_t register_list[8] = {0}, index = 0, start_address = 0;
>> +  uint32_t record_buf[24], record_buf_mem[48];
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  opcode = bits (thumb_insn_r->arm_insn, 11, 12);
>> +  opcode1 = bits (thumb_insn_r->arm_insn, 8, 12);
>> +  opcode2 =
>> bits (thumb_insn_r->arm_insn, 9, 12);
>> +
>> +  if (14 == opcode2)
>> +    {
>> +      /* POP.  */
>> +      register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
>> +      while (register_bits)
>> +        {
>> +          if (register_bits & 0x00000001)
>> +            register_list[register_count++] = 1;
>> +          register_bits = register_bits >> 1;
>> +        }
>> +      record_buf[register_count] = ARM_PS_REGNUM;
>> +      record_buf[register_count + 1] = ARM_SP_REGNUM;
>> +      thumb_insn_r->reg_rec_count = register_count +
>> 2;
>> +      for (register_count = 0; register_count < 8; register_count++)
>> +        {
>> +          if  (register_list[register_count])
>> +            {
>> +              record_buf[index] = register_count;
>> +              index++;
>> +            }
>> +        }
>> +    }
>> +  else if (10 == opcode2)
>> +    {
>> +      /* PUSH.  */
>> +      register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
>> +      regcache_raw_read_unsigned (reg_cache,
>> ARM_PC_REGNUM
>> +                                  , &u_buf.unsigned_regval);
>> +      while (register_bits)
>> +        {
>> +          if (register_bits & 0x00000001)
>> +             register_count++;
>> +          register_bits = register_bits >> 1;
>> +        }
>> +      start_address = u_buf.unsigned_regval -  \
>> +                   (4 * (bit (thumb_insn_r->arm_insn, 8) + register_count))
>> ;
>> +      thumb_insn_r->mem_rec_count = register_count;
>> +      while (register_count)
>> +        {
>> +          record_buf_mem[(register_count * 2) - 1] = start_address;
>> +          record_buf_mem[(register_count * 2) - 2] = 4;
>> +          start_address = start_address + 4;
>> +          register_count--;
>> +        }
>> +      record_buf[0] = ARM_SP_REGNUM;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (0x1E == opcode1)
>> +    {
>> +      /* BKPT insn.
>> */
>> +      /* Handle enhanced software breakpoint insn, BKPT.  */
>> +      /* CPSR is changed to be executed in ARM state,  disabling normal
>> +               interrupts, entering abort mode.  */
>> +      /* Accorindly to high vector configuration PC is set accordingly.  */
>> +      /* FIX ME ?  what if user hit breakpoint and type reverse, in
>> +               that case, we need to go back with previous CPSR and
>> +               Program Counter..  */
>> +      record_buf[0] = ARM_PS_REGNUM;
>> +      record_buf[1] =
>> ARM_LR_REGNUM;
>> +      thumb_insn_r->reg_rec_count = 2;
>> +      /* Save SPSR also; how?.  */
>> +      printf_unfiltered (_("Process record does not support instruction "
>> +                           "0x%0x at address %s.\n"),
>> +                          thumb_insn_r->arm_insn,
>> +                     paddress (thumb_insn_r->gdbarch, thumb_insn_r->this_addr));
>> +      return -1;
>> +    }
>> +  else if ((0 == opcode) || (1 == opcode))
>> +
>> {
>> +       /* ADD(5), ADD(6).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +      record_buf[0] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +  else if (2 == opcode)
>> +    {
>> +      /* ADD(7), SUB(4).  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +      record_buf[0] = ARM_SP_REGNUM;
>> +      thumb_insn_r->reg_rec_count = 1;
>> +    }
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, record_buf_mem);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 110
>> insns.  */
>> +
>> +static int
>> +thumb_handle_swi_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  struct gdbarch_tdep *tdep = gdbarch_tdep (thumb_insn_r->gdbarch);
>> +  struct regcache *reg_cache = thumb_insn_r->regcache;
>> +
>> +  uint32_t reg_val1 = 0;
>> +  uint32_t reg_src1 = 0;
>> +  uint32_t opcode1 = 0, opcode2 = 0, register_bits = 0, register_count = 0;
>> +  uint32_t register_list[8] = {0}, index = 0, start_address = 0;
>> +  uint32_t record_buf[24], record_buf_mem[48];
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  opcode1 = bits (thumb_insn_r->arm_insn, 8, 12);
>> +  opcode2 = bits (thumb_insn_r->arm_insn, 11, 12);
>> +
>> +  if (1 == opcode2)
>> +
>> {
>> +
>> +      /* LDMIA.  */
>> +      register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
>> +      /* Get Rn.  */
>> +      reg_src1 = bits (thumb_insn_r->arm_insn, 8, 10);
>> +      while (register_bits)
>> +        {
>> +          if (register_bits & 0x00000001)
>> +            register_list[register_count++] = 1;
>> +          register_bits = register_bits >> 1;
>> +        }
>> +      record_buf[register_count] = reg_src1;
>> +      thumb_insn_r->reg_rec_count = register_count + 1;
>> +      for
>> (register_count = 0; register_count < 8; register_count++)
>> +        {
>> +          if (register_list[register_count])
>> +            {
>> +              record_buf[index] = register_count;
>> +              index++;
>> +            }
>> +        }
>> +    }
>> +  else if (0 == opcode2)
>> +    {
>> +      /* It handles both STMIA.  */
>> +      register_bits = bits (thumb_insn_r->arm_insn, 0, 7);
>> +      /* Get Rn.  */
>> +      reg_src1 = bits
>> (thumb_insn_r->arm_insn, 8, 10);
>> +      regcache_raw_read_unsigned (reg_cache, reg_src1, &u_buf.unsigned_regval);
>> +      while (register_bits)
>> +        {
>> +          if (register_bits & 0x00000001)
>> +             register_count++;
>> +          register_bits = register_bits >> 1;
>> +        }
>> +      start_address = u_buf.unsigned_regval;
>> +      thumb_insn_r->mem_rec_count = register_count;
>> +      while (register_count)
>> +        {
>> +          record_buf_mem[(register_count * 2) - 1] =
>> start_address;
>> +          record_buf_mem[(register_count * 2) - 2] = 4;
>> +          start_address = start_address + 4;
>> +          register_count--;
>> +        }
>> +    }
>> +  else if (0x1F == opcode1)
>> +     {
>> +        /* Handle arm syscall insn.  */
>> +        if (tdep->arm_swi_record != NULL)
>> +          {
>> +            tdep->arm_swi_record(reg_cache);
>> +          }
>> +        else
>> +
>> {
>> +            printf_unfiltered (_("no syscall record support\n"));
>> +            return -1;
>> +          }
>> +     }
>> +
>> +  /* B(1), conditional branch is automatically taken care in process_record,
>> +        as PC is saved there.  */
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +  MEM_ALLOC (thumb_insn_r->arm_mems, thumb_insn_r->mem_rec_count, record_buf_mem);
>> +
>> +  return 0;
>> +}
>> +
>> +/* Handling opcode 111 insns.  */
>> +
>> +static int
>> +thumb_handle_branch_insn (insn_decode_record *thumb_insn_r)
>> +{
>> +  uint32_t record_buf[8];
>> +  uint32_t reg_val1 = 0;
>> +  uint32_t reg_src1 = 0;
>> +
>> uint32_t opcode = 0, immed_5 = 0;
>> +
>> +
>> +  /* BL , BLX(1).  */
>> +  record_buf[0] = ARM_PS_REGNUM;
>> +  record_buf[1] = ARM_LR_REGNUM;
>> +  thumb_insn_r->reg_rec_count = 2;
>> +
>> +  /* B(2) is automatically taken care in process_record, as PC is saved
>> +        there.  */
>> +
>> +  REG_ALLOC (thumb_insn_r->arm_regs, thumb_insn_r->reg_rec_count, record_buf);
>> +
>> +  return 0;
>> +}
>> +
>> +
>> +/* Decode arm/thumb insn depending on condition cods and opcodes; and dispatch it.  */
>> +
>> +static int
>> +decode_insn (insn_decode_record *arm_record, uint32_t insn_size)
>> +{
>> +
>> +  /* (Starting from numerical 0); bits 25, 26, 27 decodes type of arm instruction.  */
>> +  static int (*const arm_handle_insn[8])
>> +                                      (insn_decode_record*) =
>> +  {
>> +      arm_handle_data_proc_misc_ld_str_insn,    /* 000.  */
>> +      arm_handle_data_proc_imm_insn,            /* 001.  */
>> +      arm_handle_ld_st_imm_offset_insn,         /* 010.  */
>> +      arm_handle_ld_st_reg_offset_insn,         /* 011.  */
>> +      arm_handle_ld_st_multiple_insn,           /* 100.
>> */
>> +      arm_handle_brn_insn,                      /* 101.  */
>> +      arm_handle_coproc_insn,                   /* 110.  */
>> +      arm_handle_coproc_data_proc_insn          /* 111.  */
>> +  };
>> +
>> +  /* (Starting from numerical 0); bits 13,14,15 decodes type of thumb instruction.  */
>> +  static int (*const thumb_handle_insn[8])
>> +
>> (insn_decode_record*) =
>> +  { \
>> +      thumb_handle_shift_add_sub_insn,         /* 000.  */
>> +      thumb_handle_add_sub_cmp_mov_insn,       /* 001.  */
>> +      thumb_handle_ld_st_reg_offset_insn,      /* 010.  */
>> +      thumb_handle_ld_st_imm_offset_insn,      /* 011.  */
>> +      thumb_handle_ld_st_stack_insn,           /* 100.  */
>> +      thumb_handle_misc_insn,                  /* 101.  */
>> +
>> thumb_handle_swi_insn,                   /* 110.  */
>> +      thumb_handle_branch_insn                 /* 111.  */
>> +  };
>> +
>> +  struct
>> +    {
>> +      gdb_byte buf[insn_size];
>> +    } u_buf;
>> +
>> +  uint32_t ret=0, insn_id = 0;
>> +
>> +  memset (&u_buf, 0, sizeof(u_buf));
>> +  if (target_read_memory (arm_record->this_addr, &u_buf.buf[0], insn_size))
>> +    {
>> +      if (record_debug)
>> +        {
>> +          printf_unfiltered
>> (_("Process record: error reading memory at "
>> +                               "addr %s len = %d.\n"),
>> +          paddress (arm_record->gdbarch, arm_record->this_addr), insn_size);
>> +          return -1;
>> +        }
>> +    }
>> +  else if (ARM_INSN_SIZE_BYTES == insn_size)
>> +    {
>> +      arm_record->arm_insn = (uint32_t) extract_unsigned_integer (&u_buf.buf[0]
>> +             , ARM_INSN_SIZE_BYTES , gdbarch_byte_order (arm_record->gdbarch));
>> +      arm_record->cond = bits (arm_record->arm_insn, 28,
>> 31);
>> +      insn_id = bits (arm_record->arm_insn, 25, 27);
>> +      ret = (0x0F != arm_record->cond)
>> +            ? arm_handle_insn[insn_id] (arm_record)
>> +            : handle_extension_space (arm_record);
>> +    }
>> +  else if (THUMB_INSN_SIZE_BYTES == insn_size)
>> +    {
>> +      /* As thumb does not have condition codes, following field is useless.  */
>> +      arm_record->cond = -1;
>> +      arm_record->arm_insn = (uint32_t) extract_unsigned_integer (&u_buf.buf[0]
>> +           , THUMB_INSN_SIZE_BYTES , gdbarch_byte_order
>> (arm_record->gdbarch));
>> +
>> +      insn_id = bits (arm_record->arm_insn, 13, 15);
>> +      ret = thumb_handle_insn[insn_id] (arm_record);
>> +    }
>> +  else if (THUMB2_INSN_SIZE_BYTES == insn_size)
>> +    {
>> +      /* Yet to be implemented; handle thumb2 part here.  */
>> +      printf_unfiltered (_("Process record does not support instruction 0x%0x "
>> +                         "at address %s.\n"),
>> +
>> arm_record->arm_insn,
>> +                         paddress (arm_record->gdbarch, arm_record->this_addr));
>> +      ret = -1;
>> +    }
>> +  else
>> +    {
>> +      /* Throw assertion.  */
>> +      gdb_assert (0);
>> +    }
>> +
>> +  return ret;
>> +}
>> +
>> +/* Parse the current instruction and record the values of the registers and
>> +   memory that will be changed in current instruction to "record_arch_list".
>> +   Return -1 if something is wrong..  */
>> +
>> +int
>> +arm_process_record (struct gdbarch *gdbarch, struct regcache
>> *regcache,
>> +                             CORE_ADDR insn_addr)
>> +{
>> +
>> +  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
>> +  uint32_t no_of_rec = 0;
>> +  uint32_t ret = 0;
>> +  ULONGEST t_bit = 0;
>> +
>> +  struct
>> +    {
>> +      ULONGEST unsigned_regval;
>> +    } u_buf;
>> +
>> +  insn_decode_record arm_record;
>> +  memset (&u_buf, 0, sizeof(u_buf));
>> +
>> +  memset (&arm_record, 0, sizeof (insn_decode_record));
>> +  arm_record.regcache = regcache;
>> +  arm_record.this_addr = insn_addr;
>> +  arm_record.gdbarch = gdbarch;
>> +
>> +
>> +  if (record_debug > 1)
>> +    {
>> +      fprintf_unfiltered (gdb_stdlog,
>> "Process record: arm_process_record "
>> +                                      "addr = %s\n",
>> +      paddress (gdbarch, arm_record.this_addr));
>> +    }
>> +
>> +  /* Check the insn, whether it is thumb or arm one.  */
>> +
>> +  t_bit = arm_psr_thumb_bit (arm_record.gdbarch);
>> +  regcache_raw_read_unsigned (arm_record.regcache, ARM_PS_REGNUM
>> +                              , &u_buf.unsigned_regval);
>> +
>> +  if (!(u_buf.unsigned_regval & t_bit))
>> +    {
>> +      /* We are decoding arm
>> insn.  */
>> +      ret = decode_insn (&arm_record, ARM_INSN_SIZE_BYTES);
>> +    }
>> +  else
>> +    {
>> +      /* We are decoding thumb insn.  */
>> +      ret = decode_insn (&arm_record, THUMB_INSN_SIZE_BYTES);
>> +    }
>> +
>> +  if (0 == ret)
>> +    {
>> +      /* Record registers.  */
>> +      record_arch_list_add_reg (arm_record.regcache, ARM_PC_REGNUM);
>> +      if (arm_record.arm_regs)
>> +        {
>> +          for (no_of_rec = 0; no_of_rec < arm_record.reg_rec_count; no_of_rec++)
>> +
>> {
>> +              if (record_arch_list_add_reg (arm_record.regcache \
>> +                                           , (arm_record.arm_regs[no_of_rec])))
>> +              ret = -1;
>> +            }
>> +        }
>> +      /* Record memories.  */
>> +      if (arm_record.arm_mems)
>> +        {
>> +          for (no_of_rec = 0; no_of_rec < arm_record.mem_rec_count;
>> no_of_rec++)
>> +           {
>> +              if (record_arch_list_add_mem \
>> +                ((CORE_ADDR)arm_record.arm_mems[no_of_rec].addr,
>> +                arm_record.arm_mems[no_of_rec].len))
>> +                ret = -1;
>> +           }
>> +        }
>> +
>> +      if (record_arch_list_add_end ())
>> +        ret = -1;
>> +    }
>> +
>> +  if (arm_record.arm_regs)
>> +    xfree (arm_record.arm_regs);
>> +  if
>> (arm_record.arm_mems)
>> +    xfree (arm_record.arm_mems);
>> +
>> +  return ret;
>> +}
>> diff -urN arm_orig/arm-tdep.h arm_new/arm-tdep.h
>> --- arm_orig/arm-tdep.h    2011-07-28 09:40:19.000000000 +0530
>> +++ arm_new/arm-tdep.h    2011-07-28 09:41:06.000000000 +0530
>> @@ -201,6 +201,9 @@
>>    /* Return the expected next PC if FRAME is stopped at a syscall
>>       instruction.  */
>>    CORE_ADDR (*syscall_next_pc) (struct frame_info *frame);
>> +
>> +   /* Parse swi insn args, sycall record.  */
>> +  int (*arm_swi_record) (struct regcache *regcache);
>>  };
>>
>>  /* Structures used for displaced stepping.  */
>> @@ -331,6 +334,8 @@
>>     instruction?  */
>>  extern int arm_pc_is_thumb (struct gdbarch *, CORE_ADDR);
>>
>> +extern int arm_process_record (struct
>> gdbarch *gdbarch,
>> +                               struct regcache *regcache, CORE_ADDR addr);
>>  /* Functions exported from armbsd-tdep.h.  */
>>
>>  /* Return the appropriate register set for the core section identified
>>
>>
>>
>>
>> ________________________________
>> From: Tom Tromey <tromey@redhat.com>
>> To: paawan oza <paawan1982@yahoo.com>
>> Cc: gdb-patches@sourceware.org; Petr Hluzín <petr.hluzin@gmail.com>
>> Sent: Wednesday, 13 July 2011 1:29 AM
>> Subject: Re: [PATCH] arm reversible : <phase_2_complete>
>>
>>>>>>> "Oza" == paawan oza <paawan1982@yahoo.com> 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.  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.  I expect
>> there will be bugs; those can be fixed.
>>
>> You need a ChangeLog entry.  A patch of this magnitude
>> should also have
>> a NEWS entry.
>>
>> Some kind of testing would be good.  Do the existing tests in
>> gdb.reverse work with your port?  If so then I think that is sufficient
>>
>> Oza> +    unsigned int reg_len = 0; reg_len = LENGTH; \
>>
>> Just write   unsigned int reg_len = LENGTH;
>>
>> Oza> +        REGS = (uint32_t*) xmalloc (sizeof(uint32_t) * (reg_len)); \
>>
>> Mind the spaces and parens.  Better, use XNEWVEC:
>>
>>     REGS = XNEWVEC (uint32_t, reg_len);
>>
>> Oza> +        while (reg_len) \
>> Oza> +          { \
>> Oza> +            REGS[reg_len - 1] = RECORD_BUF[reg_len - 1];  \
>> Oza> +            reg_len--;  \
>> Oza> +          } \
>>
>> 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 execution state
>> Oza> (before entry to
>>
>> Oza> +decode_insn() ), contains list of to-be-modified registers and memory blocks
>> Oza> (on return from
>>
>> Your email got corrupted.  Usually this is some bad MUA setting.
>>
>> Oza> +  uint32_t mem_rec_count;       /* No of mem recors */
>>
>> Typo, "recors"
>>
>> Oza> +/* Checks ARM SBZ and SBO mendatory fields.  */
>>
>> Typo, should be "mandatory".
>>
>> Oza> +  if(!sbo)
>>
>> Spacing.
>>
>> Oza> +  if ((3 == opcode1) && (bit (arm_insn_r->arm_insn, 4)))
>>
>> Over-parenthesizing makes the code harder to read.  Please fix this.  I
>> noticed it in many places.  This specific case should read:
>>
>>   if (3 == opcode1 && bit
>> (arm_insn_r->arm_insn, 4))
>>
>> Oza> +  memset(&u_buf, 0, sizeof (u_buf));
>>
>> Spacing.  Just go through the entire patch and fix all the spacing
>> issues.
>>
>> I feel like I have mentioned this before.
>>
>> Oza> +      regcache_raw_read_unsigned (reg_cache, reg_src1
>> Oza> +                                  , &u_buf[0].unsigned_regval);
>>
>> What if this does not return REG_VALID?
>> There are multiple instances of this.
>>
>> Oza> +      gdb_assert_not_reached ("no decoding pattern found");
>>
>> It seems wrong to use an assert in this code.  At least, it is not
>> obvious to me that this represents a logic error in gdb as opposed to a
>> merely unrecognized instruction.  An unrecognized instruction can occur
>> for many reasons, e.g., a bad jump.
>>
>> Oza> +
>>   if ((8 == arm_insn_r->opcode) || (10 == arm_insn_r->opcode)
>> Oza> +      || (12 == arm_insn_r->opcode) || (14 == arm_insn_r->opcode)
>> Oza> +      || (9 == arm_insn_r->opcode) || (11 == arm_insn_r->opcode)
>> Oza> +      || (13 == arm_insn_r->opcode) || (15 == arm_insn_r->opcode)
>> Oza> +      || (0 == arm_insn_r->opcode) || (2 == arm_insn_r->opcode)
>> Oza> +      || (4 == arm_insn_r->opcode) || (6 == arm_insn_r->opcode)
>> Oza> +      || (1 == arm_insn_r->opcode) || (3 == arm_insn_r->opcode)
>> Oza> +      || (5 == arm_insn_r->opcode) || (7 == arm_insn_r->opcode))
>>
>> This reads very oddly.  Is there a particular reason behind the ordering
>> (if so -- document).  If not, isn't
>> this:
>>
>>   if (arm_insn_r->opcode >= 0 && arm_insn_r->opcode <= 15)
>>
>> There are other odd-looking conditions like this.
>>
>> Oza> +              default:
>> Oza> +                gdb_assert_not_reached ("Invalid addressing mode for insn");
>>
>> Again, assert seems wrong.
>>
>> I'm afraid I ran out of steam here.  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.  I want this patch to go in, but first it
>> must comply to the usual gdb standards.
>>
>> Tom
>>
>



More information about the Gdb-patches mailing list