This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 6/7] Support for recording aarch64 advanced SIMD instructions


On 19 September 2014 04:01, Omair Javaid <omair.javaid@linaro.org> wrote:
> On 2 September 2014 20:01, Will Newton <will.newton@linaro.org> wrote:
>> On 29 August 2014 14:41, Omair Javaid <omair.javaid@linaro.org> wrote:
>>> Updated patch after incorporating suggestions.
>>>
>>> gdb:
>>>
>>> 2014-08-28  Omair Javaid  <omair.javaid@linaro.org>
>>>
>>>         * aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Add handler
>>>         for data processing SIMD and floating point insns.
>>>         (aarch64_record_asimd_load_store): Add handler to record ASIMD load
>>>         store insns.
>>>         (aarch64_record_load_store): Install record handler
>>>         aarch64_record_asimd_load_store.
>>>         (aarch64_record_decode_insn_handler): Install record handler
>>>         aarch64_record_data_proc_simd_fp.
>>>
>>> ---
>>>  gdb/aarch64-tdep.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>>  1 file changed, 226 insertions(+), 2 deletions(-)
>>
>> This looks OK to me.
>>
>>> diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
>>> index c6da25a..9437280 100644
>>> --- a/gdb/aarch64-tdep.c
>>> +++ b/gdb/aarch64-tdep.c
>>> @@ -2986,6 +2986,144 @@ aarch64_record_branch_except_sys (insn_decode_record *aarch64_insn_r)
>>>    return AARCH64_RECORD_SUCCESS;
>>>  }
>>>
>>> +/* Record handler for advanced SIMD load and store instructions.  */
>>> +static unsigned int
>>> +aarch64_record_asimd_load_store (insn_decode_record *aarch64_insn_r)
>>> +{
>>> +  CORE_ADDR address;
>>> +  uint64_t addr_offset = 0;
>>> +  uint32_t record_buf[24];
>>> +  uint64_t record_buf_mem[24];
>>> +  uint32_t reg_rn, reg_rt, reg_rm;
>>> +  uint32_t reg_index = 0, mem_index = 0;
>>> +  uint8_t eindex, rindex, sindex, reg_tt, replicate;
>>> +  uint8_t elements, esize, rpt, selem, single, scale;
>>> +  uint8_t opcode_bits, size_bits, ld_flag, data_size, wback;
>>> +
>>> +  reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>>> +  reg_rn = bits (aarch64_insn_r->aarch64_insn, 5, 9);
>>> +  reg_rm = bits (aarch64_insn_r->aarch64_insn, 16, 20);
>>> +
>>> +  wback = bit (aarch64_insn_r->aarch64_insn, 23);
>>> +  single = bit (aarch64_insn_r->aarch64_insn, 24);
>>> +  ld_flag = bit (aarch64_insn_r->aarch64_insn, 22);
>>> +  size_bits = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>>> +  opcode_bits = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>>> +  regcache_raw_read_unsigned (aarch64_insn_r->regcache, reg_rn, &address);
>>> +
>>> +  if (single)
>>> +    {
>>> +      scale = opcode_bits >> 2;
>>> +      selem = ((opcode_bits & 0x02) |
>>> +              bit (aarch64_insn_r->aarch64_insn, 21)) + 1;
>>> +      replicate = 0;
>>> +      switch (scale)
>>> +        {
>>> +        case 2:
>>> +          if (!(size_bits & 0x01) && ((size_bits >> 1) & 0x01))
>>> +            scale = 3;
>>> +          break;
>>> +        case 3:
>>> +          scale = size_bits;
>>> +          replicate = 1;
>>> +          break;
>>> +        default:
>>> +          break;
>>> +        }
>>> +      esize = 8 << scale;
>>> +      if (replicate)
>>> +        for (sindex = 0; sindex < selem; sindex++)
>>> +          {
>>> +            record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>>> +            reg_rt = (reg_rt + 1) % 32;
>>> +          }
>>> +      else
>>> +        {
>>> +          for (sindex = 0; sindex < selem; sindex++)
>>> +            if (ld_flag)
>>> +              record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
>>> +            else
>>> +              {
>>> +                record_buf_mem[mem_index++] = esize / 8;
>>> +                record_buf_mem[mem_index++] = address + addr_offset;
>>> +              }
>>> +            addr_offset = addr_offset + (esize / 8);
>>> +            reg_rt = (reg_rt + 1) % 32;
>>> +        }
>>> +    }
>>> +  else
>>> +    {
>>> +      esize = 8 << size_bits;
>>> +      if (bit (aarch64_insn_r->aarch64_insn, 30))
>>> +        elements = 128 / esize;
>>> +      else
>>> +        elements = 64 / esize;
>>> +
>>> +      switch (opcode_bits)
>>> +        {
>>> +        case 0:
>>> +          rpt = 1;
>>> +          selem = 4;
>>> +          break;
>>> +        case 2:
>>> +          rpt = 4;
>>> +          selem = 1;
>>> +          break;
>>> +        case 4:
>>> +          rpt = 1;
>>> +          selem = 3;
>>> +          break;
>>> +        case 6:
>>> +          rpt = 3;
>>> +          selem = 1;
>>> +          break;
>>> +        case 7:
>>> +          rpt = 1;
>>> +          selem = 1;
>>> +          break;
>>> +        case 8:
>>> +          rpt = 1;
>>> +          selem = 2;
>>> +          break;
>>> +        case 10:
>>> +          rpt = 2;
>>> +          selem = 1;
>>> +          break;
>>> +        default:
>>> +          return AARCH64_RECORD_UNSUPPORTED;
>>> +          break;
>>> +        }
>>> +      for (rindex = 0; rindex < rpt; rindex++)
>>> +        for (eindex = 0; eindex < elements; eindex++)
>>> +          {
>>> +            reg_tt = (reg_rt + rindex) % 32;
>>> +            for (sindex = 0; sindex < selem; sindex++)
>>> +              {
>>> +                if (ld_flag)
>>> +                  record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
>>> +                else
>>> +                  {
>>> +                    record_buf_mem[mem_index++] = esize / 8;
>>> +                    record_buf_mem[mem_index++] = address + addr_offset;
>>> +                  }
>>> +                addr_offset = addr_offset + (esize / 8);
>>> +                reg_tt = (reg_tt + 1) % 32;
>>> +              }
>>> +          }
>>> +    }
>>> +
>>> +  if (wback)
>>> +    record_buf[reg_index++] = reg_rn;
>>> +
>>> +  aarch64_insn_r->reg_rec_count = reg_index;
>>> +  aarch64_insn_r->mem_rec_count = mem_index / 2;
>>> +  MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>>> +             record_buf_mem);
>>> +  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>>> +             record_buf);
>>> +  return AARCH64_RECORD_SUCCESS;
>>> +}
>>> +
>>>  /* Record handler for load and store instructions.  */
>>>  static unsigned int
>>>  aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>> @@ -3224,7 +3362,7 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>>      }
>>>    /* Advanced SIMD load/store instructions.  */
>>>    else
>>> -    return AARCH64_RECORD_UNSUPPORTED;
>>> +    return aarch64_record_asimd_load_store (aarch64_insn_r);
>>>
>>>    MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
>>>               record_buf_mem);
>>> @@ -3232,6 +3370,92 @@ aarch64_record_load_store (insn_decode_record *aarch64_insn_r)
>>>               record_buf);
>>>    return AARCH64_RECORD_SUCCESS;
>>>  }
>>> +
>>> +/* Record handler for data processing SIMD and floating point instructions.  */
>>> +
>>> +static unsigned int
>>> +aarch64_record_data_proc_simd_fp (insn_decode_record *aarch64_insn_r)
>>> +{
>>> +  uint8_t insn_bit21, opcode, rmode, reg_rd;
>>> +  uint8_t insn_bits24_27, insn_bits28_31, insn_bits10_11, insn_bits12_15;
>>> +  uint8_t insn_bits11_14;
>>> +  uint32_t record_buf[2];
>>> +
>>> +  insn_bits24_27 = bits (aarch64_insn_r->aarch64_insn, 24, 27);
>>> +  insn_bits28_31 = bits (aarch64_insn_r->aarch64_insn, 28, 31);
>>> +  insn_bits10_11 = bits (aarch64_insn_r->aarch64_insn, 10, 11);
>>> +  insn_bits12_15 = bits (aarch64_insn_r->aarch64_insn, 12, 15);
>>> +  insn_bits11_14 = bits (aarch64_insn_r->aarch64_insn, 11, 14);
>>> +  opcode = bits (aarch64_insn_r->aarch64_insn, 16, 18);
>>> +  rmode = bits (aarch64_insn_r->aarch64_insn, 19, 20);
>>> +  reg_rd = bits (aarch64_insn_r->aarch64_insn, 0, 4);
>>> +  insn_bit21 = bit (aarch64_insn_r->aarch64_insn, 21);
>>> +
>>> +  if ((insn_bits28_31 & 0x05) == 0x01 && insn_bits24_27 == 0x0e)
>>> +    {
>>> +      /* Floating point - fixed point conversion instructions.  */
>>> +      if (!insn_bit21)
>>> +        if ((opcode >> 1) == 0x0 && rmode == 0x03)
>>> +          record_buf[0] = reg_rd;
>>> +        else
>>> +          record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +      /* Floating point - conditional compare instructions.  */
>>> +      else if (insn_bits10_11 == 0x01)
>>> +        record_buf[0] = AARCH64_CPSR_REGNUM;
>>> +      /* Floating point - data processing (2-source) and
>>> +         conditional select instructions.  */
>>> +      else if (insn_bits10_11 == 0x02 || insn_bits10_11 == 0x03)
>>> +        record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +      else if (insn_bits10_11 == 0x00)
>>> +        {
>>> +          /* Floating point - immediate instructions.  */
>>> +          if ((insn_bits12_15 & 0x01) == 0x01 || (insn_bits12_15 & 0x07) == 0x04)
>>> +            record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +          /* Floating point - compare instructions.  */
>>> +          else if ((insn_bits12_15 & 0x03) == 0x02)
>>> +            record_buf[0] = AARCH64_CPSR_REGNUM;
>>> +          /* Floating point - integer conversions instructions.  */
>>> +          if (insn_bits12_15 == 0x00)
>>> +            {
>>> +              /* Convert float to integer instruction.  */
>>> +              if (!(opcode >> 1) || ((opcode >> 1) == 0x02 && !rmode))
>>> +                record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>> +              /* Convert integer to float instruction.  */
>>> +              else if ((opcode >> 1) == 0x01 && !rmode)
>>> +                record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +              /* Move float to integer instruction.  */
>>> +              else if ((opcode >> 1) == 0x03)
>>> +                {
>>> +                  if (!(opcode & 0x01))
>>> +                    record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>> +                  else
>>> +                    record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +                }
>>> +            }
>>> +        }
>>> +    }
>>> +  else if ((insn_bits28_31 & 0x09) == 0x00 && insn_bits24_27 == 0x0E)
>>> +    {
>>> +      /* Advanced SIMD copy instructions.  */
>>> +      if (!bits (aarch64_insn_r->aarch64_insn, 21, 23) &&
>>> +          !bit (aarch64_insn_r->aarch64_insn, 15) &&
>>> +          bit (aarch64_insn_r->aarch64_insn, 10))
>>> +        if (insn_bits11_14 == 0x05 || insn_bits11_14 == 0x07)
>>> +          record_buf[0] = reg_rd + AARCH64_X0_REGNUM;
>>> +        else
>>> +          record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +      else
>>> +        record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +    }
>>> +  /* All remaining floating point or advanced SIMD instructions.  */
>>> +  else
>>> +    record_buf[0] = reg_rd + AARCH64_V0_REGNUM;
>>> +
>>> +  REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
>>> +             record_buf);
>>> +  return AARCH64_RECORD_SUCCESS;
>>> +}
>>> +
>>>  /* Decodes insns type and invokes its record handler.  */
>>>
>>>  static unsigned int
>>> @@ -3262,7 +3486,7 @@ aarch64_record_decode_insn_handler (insn_decode_record *aarch64_insn_r)
>>>
>>>    /* Data processing - SIMD and floating point instructions.  */
>>>    if (ins_bit25 && ins_bit26 && ins_bit27)
>>> -    return AARCH64_RECORD_UNSUPPORTED;
>>> +    return aarch64_record_data_proc_simd_fp (aarch64_insn_r);
>>>
>>>    return AARCH64_RECORD_UNSUPPORTED;
>>>  }
>>> --
>>> 1.9.1
>>>
>>
>>
>>
>> --
>> Will Newton
>> Toolchain Working Group, Linaro
>
> Ping! Are there any further comments for this patch? Kindly help me
> approve this patch series.

ping!


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]